/// <summary> /// Writes the specified entities to a local temporary file after download. /// </summary> /// <param name="downloadParameters"></param> /// <returns></returns> protected async Task <List <BulkEntity> > DownloadEntitiesAsync( DownloadParameters downloadParameters, Progress <BulkOperationProgressInfo> progress, CancellationToken cancellationToken) { // The system temp directory will be used if another working directory is not specified. If you are // using a cloud service such as Azure you'll want to ensure you do not exceed the file or directory limits. // You can specify a different working directory for each BulkServiceManager instance. BulkServiceManager.WorkingDirectory = FileDirectory; // The DownloadEntitiesAsync method returns IEnumerable<BulkEntity>, so the download file will not // be accessible e.g. for CleanupTempFiles until you iterate over the result e.g. via ToList(). var resultEntities = (await BulkServiceManager.DownloadEntitiesAsync( parameters: downloadParameters, progress: progress, cancellationToken: cancellationToken)).ToList(); // The CleanupTempFiles method removes all files (not sub-directories) within the working directory, // whether or not the files were created by this BulkServiceManager instance. //BulkServiceManager.CleanupTempFiles(); return(resultEntities); }
public async override Task RunAsync(AuthorizationData authorizationData) { try { ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment; CampaignManagementExampleHelper = new CampaignManagementExampleHelper(this.OutputStatusMessage); BulkServiceManager = new BulkServiceManager(authorizationData, environment); BulkServiceManager.StatusPollIntervalInMilliseconds = 5000; var progress = new Progress <BulkOperationProgressInfo>(x => OutputStatusMessage(string.Format("{0} % Complete", x.PercentComplete.ToString(CultureInfo.InvariantCulture)))); #region Download // In this example we will download all ad groups in the account. var entities = new[] { DownloadEntity.AdGroups, }; // You can limit by specific campaign IDs and request performance data. var downloadParameters = new DownloadParameters { CampaignIds = null, DataScope = DataScope.EntityData, PerformanceStatsDateRange = null, DownloadEntities = entities, FileType = FileType, LastSyncTimeInUTC = null, ResultFileDirectory = FileDirectory, ResultFileName = DownloadFileName, OverwriteResultFile = true }; // You can submit a download or upload request and the BulkServiceManager will automatically // return results. The BulkServiceManager abstracts the details of checking for result file // completion, and you don't have to write any code for results polling. var bulkFilePath = await BulkServiceManager.DownloadFileAsync(downloadParameters); OutputStatusMessage("Downloaded all ad groups in the account.\n"); #endregion Download #region Parse Reader = new BulkFileReader(bulkFilePath, ResultFileType.FullDownload, FileType); var bulkAdGroups = Reader.ReadEntities().ToList().OfType <BulkAdGroup>().ToList(); OutputBulkAdGroups(bulkAdGroups); Writer = new BulkFileWriter(FileDirectory + UploadFileName); // We will activate ad groups for one month starting from today as an example. var nextMonth = DateTime.UtcNow.AddMonths(1); // Within the downloaded records, find all ad groups that you want to update. foreach (var bulkAdGroup in bulkAdGroups) { var adGroup = bulkAdGroup.AdGroup; if (adGroup != null && bulkAdGroup.IsExpired) { // For best performance, only upload the properties that you want to update. Writer.WriteEntity(new BulkAdGroup { CampaignId = bulkAdGroup.CampaignId, AdGroup = new AdGroup { Id = adGroup.Id, EndDate = new Microsoft.BingAds.V12.CampaignManagement.Date { Month = nextMonth.Month, Day = nextMonth.Day, Year = nextMonth.Year }, Status = AdGroupStatus.Active, } }); } } Reader.Dispose(); Writer.Dispose(); #endregion Parse #region Upload // Upload the local file that we already prepared var fileUploadParameters = new FileUploadParameters { ResultFileDirectory = FileDirectory, CompressUploadFile = true, ResultFileName = ResultFileName, OverwriteResultFile = true, UploadFilePath = FileDirectory + UploadFileName, ResponseMode = ResponseMode.ErrorsAndResults }; var resultFilePath = await BulkServiceManager.UploadFileAsync(fileUploadParameters, progress, CancellationToken.None); OutputStatusMessage("Updated ad groups.\n"); Reader = new BulkFileReader(resultFilePath, ResultFileType.Upload, FileType); bulkAdGroups = Reader.ReadEntities().ToList().OfType <BulkAdGroup>().ToList(); OutputBulkAdGroups(bulkAdGroups); Reader.Dispose(); #endregion Upload #region Entities // We can make the same update without explicitly reading or writing a local file. // When working with entities a file is downloaded to the temp directory, // although you don't need to manage it. var downloadEntities = await BulkServiceManager.DownloadEntitiesAsync(downloadParameters); OutputStatusMessage("Downloaded all ad groups in the account.\n"); bulkAdGroups = downloadEntities.ToList().OfType <BulkAdGroup>().ToList(); OutputBulkAdGroups(bulkAdGroups); var uploadEntities = new List <BulkEntity>(); foreach (var bulkAdGroup in bulkAdGroups) { var adGroup = bulkAdGroup.AdGroup; if (adGroup != null && bulkAdGroup.IsExpired) { // Instead of Writer.WriteEntity, we will add to the in-memory list uploadEntities.Add(new BulkAdGroup { CampaignId = bulkAdGroup.CampaignId, AdGroup = new AdGroup { Id = adGroup.Id, EndDate = new Microsoft.BingAds.V12.CampaignManagement.Date { Month = nextMonth.Month, Day = nextMonth.Day, Year = nextMonth.Year }, Status = AdGroupStatus.Active, } }); } } var entityUploadParameters = new EntityUploadParameters { Entities = uploadEntities, ResponseMode = ResponseMode.ErrorsAndResults, }; var resultEntities = await BulkServiceManager.UploadEntitiesAsync(entityUploadParameters, progress, CancellationToken.None); OutputStatusMessage("Updated ad groups.\n"); bulkAdGroups = resultEntities.ToList().OfType <BulkAdGroup>().ToList(); OutputBulkAdGroups(bulkAdGroups); #endregion Entities } // 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 Bulk service exceptions catch (FaultException <Microsoft.BingAds.V12.Bulk.AdApiFaultDetail> ex) { OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (FaultException <Microsoft.BingAds.V12.Bulk.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 (BulkOperationInProgressException ex) { OutputStatusMessage("The result file for the bulk operation is not yet available for download."); OutputStatusMessage(ex.Message); } catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex) { OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (BulkOperationCouldNotBeCompletedException <UploadStatus> ex) { OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } }
public async override Task RunAsync(AuthorizationData authorizationData) { try { CustomerService = new ServiceClient <ICustomerManagementService>(authorizationData); BulkService = new BulkServiceManager(authorizationData); var progress = new Progress <BulkOperationProgressInfo>(x => OutputStatusMessage(string.Format("{0} % Complete", x.PercentComplete.ToString(CultureInfo.InvariantCulture)))); Dictionary <long, List <long> > targetToEntities = new Dictionary <long, List <long> >(); Dictionary <long, List <Dictionary <long, KeyValuePair <long, string> > > > targetToEntities2 = new Dictionary <long, List <Dictionary <long, KeyValuePair <long, string> > > >(); var downloadParameters = new DownloadParameters { CampaignIds = null, Entities = BulkDownloadEntity.AdGroupTargets | BulkDownloadEntity.CampaignTargets, ResultFileDirectory = FileDirectory, ResultFileName = DownloadFileName, OverwriteResultFile = true, LastSyncTimeInUTC = null }; // Search for the Bing Ads accounts that the user can access. var getUserResponse = await GetUserAsync(null); var user = getUserResponse.User; var accounts = await SearchAccountsByUserIdAsync(user.Id); foreach (var account in accounts) { var linkToUI = string.Format("https://ui.bingads.microsoft.com/Campaign/Campaigns?cid={0}&aid={1}#/customer/{0}/account/{1}/campaign", authorizationData.CustomerId, account.Id); OutputStatusMessage(string.Format("Downloading targets for account {0} \n", account.Number)); OutputStatusMessage(linkToUI); authorizationData.AccountId = (long)account.Id; BulkService = new BulkServiceManager(authorizationData); var downloadEntities = (await BulkService.DownloadEntitiesAsync(downloadParameters)).ToList(); var adGroupTargetResults = downloadEntities.OfType <Microsoft.BingAds.V10.Bulk.Entities.BulkAdGroupTarget>().ToList(); foreach (var entity in adGroupTargetResults) { MapTargetToEntity(targetToEntities, (long)entity.Target.Id, (long)entity.AdGroupId); MapTargetToEntity2( targetToEntities2, authorizationData.AccountId, (long)entity.Target.Id, (long)entity.AdGroupId, "AdGroup" ); } var campaignTargetResults = downloadEntities.OfType <Microsoft.BingAds.V10.Bulk.Entities.BulkCampaignTarget>().ToList(); foreach (var entity in campaignTargetResults) { MapTargetToEntity(targetToEntities, (long)entity.Target.Id, (long)entity.CampaignId); MapTargetToEntity2( targetToEntities2, authorizationData.AccountId, (long)entity.Target.Id, (long)entity.CampaignId, "Campaign" ); } } OutputStatusMessage("\nView 1: By Target Id:"); foreach (var dict in targetToEntities) { if (dict.Value.Count() > 1) { OutputStatusMessage(string.Format("\nTargetId {0} is shared by the following entities:", dict.Key)); OutputStatusMessage(string.Join("\r\n", dict.Value.Select(id => string.Format("{0}", id)))); } } OutputStatusMessage("\nView 2: With Account Detail:"); OutputStatusMessage("\nTargetId, AccountId, EntityId, EntityType"); foreach (var targetDictionary in targetToEntities2) { if (targetDictionary.Value.Count() > 1) { foreach (var accountDictionary in targetDictionary.Value) { foreach (var accountIdKey in accountDictionary.Keys) { OutputStatusMessage( string.Format("{0}, {1}, {2}, {3}", targetDictionary.Key, accountIdKey, accountDictionary[accountIdKey].Key, // EntityId accountDictionary[accountIdKey].Value // EntityType e.g. Campaign or AdGroup )); } } } } } // Catch Microsoft Account authorization exceptions. catch (OAuthTokenRequestException ex) { OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description)); } // Catch Bulk service exceptions catch (FaultException <Microsoft.BingAds.V10.Bulk.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 (BulkOperationInProgressException ex) { OutputStatusMessage("The result file for the bulk operation is not yet available for download."); OutputStatusMessage(ex.Message); } catch (BulkOperationCouldNotBeCompletedException <DownloadStatus> ex) { OutputStatusMessage(string.Join("; ", ex.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message)))); } catch (Exception ex) { OutputStatusMessage(ex.Message); } finally { if (Reader != null) { Reader.Dispose(); } if (Writer != null) { Writer.Dispose(); } } }