/// <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);
        }
Exemple #2
0
        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();
                }
            }
        }