Codebeispiel für Massendownloadanforderungen

In diesem Beispiel wird veranschaulicht, wie Kampagnen, Anzeigengruppen und Anzeigen mithilfe des Massendiensts in eine .csv-Datei heruntergeladen werden.

Tipp

Verwenden Sie die Sprachauswahl im Dokumentationsheader, um C#, Java, Php oder Python auszuwählen.

Informationen zum Abrufen von Zugriffs- und Aktualisierungstoken für Ihren Microsoft Advertising-Benutzer und Zum ersten Dienstaufruf mithilfe der Bing Ads-API finden Sie im Schnellstarthandbuch . Sie sollten den Leitfaden für die ersten Schritte und exemplarische Vorgehensweisen für Ihre bevorzugte Sprache lesen, z. B. C#, Java, Php und Python.

Unterstützende Dateien für C#-, Java-, Php- und Python-Beispiele sind auf GitHub verfügbar. Sie können jedes Repository klonen oder Codeausschnitte nach Bedarf erneut verwenden.

using System;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds;
using Microsoft.BingAds.V13.Bulk;
using Microsoft.BingAds.V13.Bulk.Entities;
using System.Threading;
using System.Collections.Generic;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to download entities such as campaigns and ads with the Bulk service.
    /// </summary>
    public class BulkServiceManagerDemo : BulkExampleBase
    {
        public override string Description
        {
            get { return "Bulk Service Manager Download Demo | Bulk V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;
                
                BulkServiceManager = new BulkServiceManager(
                    authorizationData: authorizationData,
                    apiEnvironment: environment);
                BulkServiceManager.StatusPollIntervalInMilliseconds = 5000;

                // Track download or upload progress

                var progress = new Progress<BulkOperationProgressInfo>(x =>
                    OutputStatusMessage(string.Format("{0} % Complete",
                        x.PercentComplete.ToString(CultureInfo.InvariantCulture))));

                // Some BulkServiceManager operations can be cancelled after a time interval. 

                var tokenSource = new CancellationTokenSource();
                tokenSource.CancelAfter(TimeoutInMilliseconds);
                
                // Download all campaigns, ad groups, and ads in the account.

                var entities = new[] {
                    DownloadEntity.Campaigns,
                    DownloadEntity.AdGroups,
                    DownloadEntity.Ads,
                };

                // DownloadParameters is used for Option A below.
                var downloadParameters = new DownloadParameters
                {
                    CampaignIds = null,
                    DataScope = DataScope.EntityData | DataScope.QualityScoreData,
                    DownloadEntities = entities,
                    FileType = FileType,
                    LastSyncTimeInUTC = null,
                    ResultFileDirectory = FileDirectory,
                    ResultFileName = DownloadFileName,
                    OverwriteResultFile = true
                };

                // SubmitDownloadParameters is used for Option B and Option C below.
                var submitDownloadParameters = new SubmitDownloadParameters
                {
                    CampaignIds = null,
                    DataScope = DataScope.EntityData | DataScope.QualityScoreData,
                    DownloadEntities = entities,
                    FileType = FileType,
                    LastSyncTimeInUTC = null
                };

                // Option A - Background Completion with BulkServiceManager
                // 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.

                OutputStatusMessage("-----\nAwaiting Background Completion with DownloadFileAsync...");
                await BackgroundCompletionAsync(
                    downloadParameters: downloadParameters,
                    progress: progress,
                    cancellationToken: tokenSource.Token);

                // Alternatively we can use DownloadEntitiesAsync if we want to work with the entities in memory.
                // If you enable this option the result file from BackgroundCompletionAsync will also be deleted
                // if written to the same working directory.
                OutputStatusMessage("-----\nAwaiting Background Completion with DownloadEntitiesAsync...");
                var downloadEntities = await DownloadEntitiesAsync(
                    downloadParameters: downloadParameters,
                    progress: progress,
                    cancellationToken: tokenSource.Token);

                // Option B - Submit and Download with BulkServiceManager
                // Submit the download request and then use the BulkDownloadOperation result to 
                // track status until the download is complete e.g. either using
                // TrackAsync or GetStatusAsync.

                OutputStatusMessage("-----\nAwaiting Submit, Track, and Download...");
                await SubmitTrackDownloadAsync(
                    submitDownloadParameters: submitDownloadParameters,
                    progress: progress,
                    cancellationToken: tokenSource.Token);

                // A second variation of Option B. 
                // See SubmitTrackDownloadAsync for details. 

                OutputStatusMessage("-----\nAwaiting Submit, Poll, and Download...");
                await SubmitTrackDownloadAsync(
                    submitDownloadParameters: submitDownloadParameters,
                    progress: progress,
                    cancellationToken: tokenSource.Token);

                // Option C - Download Results with BulkServiceManager
                // If for any reason you have to resume from a previous application state, 
                // you can use an existing download request identifier and use it 
                // to download the result file. 

                // For example you might have previously retrieved a request ID using SubmitDownloadAsync.

                var bulkDownloadOperation = await BulkServiceManager.SubmitDownloadAsync(
                    parameters: submitDownloadParameters);
                var requestId = bulkDownloadOperation.RequestId;

                // Given the request ID above, you can resume the workflow and download the bulk file.
                // The download request identifier is valid for two days. 
                // If you do not download the bulk file within two days, you must request it again.

                OutputStatusMessage("-----\nAwaiting Download Results...");
                await DownloadResultsAsync(
                    requestId: requestId,
                    authorizationData: authorizationData,
                    progress: progress,
                    cancellationToken: tokenSource.Token);
            }
            // 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.V13.Bulk.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(String.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.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);
            }
        }

        /// <summary>
        /// Writes the specified entities to a local temporary file prior to upload.  
        /// </summary>
        /// <param name="uploadEntities"></param>
        /// <returns></returns>
        protected async Task<List<BulkEntity>> UploadEntitiesAsync(
            IEnumerable<BulkEntity> uploadEntities,
            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;
                        
            var entityUploadParameters = new EntityUploadParameters
            {
                Entities = uploadEntities,
                OverwriteResultFile = true,
                ResultFileDirectory = FileDirectory,
                ResultFileName = ResultFileName,
                ResponseMode = ResponseMode.ErrorsAndResults
            };

            // The UploadEntitiesAsync method returns IEnumerable<BulkEntity>, so the result file will not
            // be accessible e.g. for CleanupTempFiles until you iterate over the result e.g. via ToList().

            var resultEntities = (await BulkServiceManager.UploadEntitiesAsync(
                parameters: entityUploadParameters,
                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;
        }

        /// <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;
        }

        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="downloadParameters"></param>
        /// <param name="progress"></param>
        /// <returns></returns>
        private async Task BackgroundCompletionAsync(
            DownloadParameters downloadParameters, 
            Progress<BulkOperationProgressInfo> progress,
            CancellationToken cancellationToken)
        {
            var resultFilePath = await BulkServiceManager.DownloadFileAsync(
                parameters: downloadParameters, 
                progress: progress, 
                cancellationToken: cancellationToken);
            OutputStatusMessage(string.Format("Download result file: {0}", resultFilePath));
        }

        /// <summary>
        /// Submit the download request and then use the BulkDownloadOperation result to 
        /// track status until the download is complete using TrackAsync.
        /// </summary>
        /// <param name="submitDownloadParameters"></param>
        /// <returns></returns>
        private async Task SubmitTrackDownloadAsync(
            SubmitDownloadParameters submitDownloadParameters,
            Progress<BulkOperationProgressInfo> progress,
            CancellationToken cancellationToken)
        {
            var bulkDownloadOperation = await BulkServiceManager.SubmitDownloadAsync(submitDownloadParameters);
            
            BulkOperationStatus<DownloadStatus> downloadStatus = await bulkDownloadOperation.TrackAsync(
                progress: progress,
                cancellationToken: cancellationToken);
            
            var resultFilePath = await bulkDownloadOperation.DownloadResultFileAsync(
                localResultDirectoryName: FileDirectory,
                localResultFileName: ResultFileName,
                decompress: true,
                overwrite: true // Set this value true if you want to overwrite the same file.
            );   

            OutputStatusMessage(string.Format("Download result file: {0}", resultFilePath));
        }

        /// <summary>
        /// Submit the download request and then use the BulkDownloadOperation result to 
        /// track status until the download is complete using GetStatusAsync.
        /// </summary>
        /// <param name="submitDownloadParameters"></param>
        /// <returns></returns>
        private async Task SubmitPollDownloadAsync(
            SubmitDownloadParameters submitDownloadParameters)
        {
            var bulkDownloadOperation = await BulkServiceManager.SubmitDownloadAsync(submitDownloadParameters);
            
            BulkOperationStatus<DownloadStatus> downloadStatus;
            var waitTime = new TimeSpan(0, 0, 5);

            for (int i = 0; i < 24; i++)
            {
                Thread.Sleep(waitTime);

                downloadStatus = await bulkDownloadOperation.GetStatusAsync();

                if (downloadStatus.Status == DownloadStatus.Completed)
                {
                    break;
                }
            }

            var resultFilePath = await bulkDownloadOperation.DownloadResultFileAsync(
                localResultDirectoryName: FileDirectory,
                localResultFileName: ResultFileName,
                decompress: true,
                overwrite: true // Set this value true if you want to overwrite the same file.
            );

            OutputStatusMessage(string.Format("Download result file: {0}", resultFilePath));
        }

        /// <summary>
        /// If for any reason you have to resume from a previous application state, 
        /// you can use an existing download request identifier and use it 
        /// to download the result file. Use TrackAsync to indicate that the application 
        /// should wait to ensure that the download status is completed.
        /// </summary>
        /// <param name="requestId"></param>
        /// <param name="authorizationData"></param>
        /// <returns></returns>
        private async Task DownloadResultsAsync(
            string requestId,
            AuthorizationData authorizationData,
            Progress<BulkOperationProgressInfo> progress,
            CancellationToken cancellationToken)
        {
            var bulkDownloadOperation = new BulkDownloadOperation(requestId, authorizationData);

            // Use TrackAsync to indicate that the application should wait to ensure that 
            // the download status is completed.
            var bulkOperationStatus = await bulkDownloadOperation.TrackAsync(
                progress: progress,
                cancellationToken: cancellationToken);

            var resultFilePath = await bulkDownloadOperation.DownloadResultFileAsync(
                localResultDirectoryName: FileDirectory,
                localResultFileName: ResultFileName,
                decompress: true,
                overwrite: true);   // Set this value true if you want to overwrite the same file.

            OutputStatusMessage(string.Format("Download result file: {0}", resultFilePath));
            OutputStatusMessage(string.Format("Status: {0}", bulkOperationStatus.Status));
            OutputStatusMessage(string.Format("TrackingId: {0}", bulkOperationStatus.TrackingId));
        }
    }
}
package com.microsoft.bingads.examples.v13;

import com.microsoft.bingads.v13.bulk.entities.*;
import com.microsoft.bingads.v13.bulk.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.net.URISyntaxException;
import java.util.concurrent.TimeoutException;

public class BulkServiceManagerDemo extends BulkExampleBase {
    
    public static void main(String[] args) {
        
        BulkEntityIterable downloadEntities = null;

        try {
            authorizationData = getAuthorizationData();

            BulkServiceManager = new BulkServiceManager(
                    authorizationData, 
                    API_ENVIRONMENT);
            
            BulkServiceManager.setStatusPollIntervalInMilliseconds(5000);
            
            // Download all campaigns, ad groups, and ads in the account.

            ArrayOfDownloadEntity entities = new ArrayOfDownloadEntity();
            entities.getDownloadEntities().add(DownloadEntity.CAMPAIGNS);
            entities.getDownloadEntities().add(DownloadEntity.AD_GROUPS);
            entities.getDownloadEntities().add(DownloadEntity.ADS);

            // Optionally you can request quality score data for the requested bulk records.

            List<DataScope> dataScopes = new ArrayList<DataScope>();
            dataScopes.add(DataScope.ENTITY_DATA);
            dataScopes.add(DataScope.QUALITY_SCORE_DATA);

            // DownloadParameters is used for Option A below.

            DownloadParameters downloadParameters = new DownloadParameters();
            downloadParameters.setCampaignIds(null);
            downloadParameters.setDataScope(dataScopes);
            downloadParameters.setDownloadEntities(entities);
            downloadParameters.setFileType(DownloadFileType.CSV);
            downloadParameters.setLastSyncTimeInUTC(null); 
            downloadParameters.setResultFileDirectory(new File(FileDirectory));
            downloadParameters.setResultFileName(DownloadFileName);
            downloadParameters.setOverwriteResultFile(true);

            // SubmitDownloadParameters is used for Option B and Option C below.

            SubmitDownloadParameters submitDownloadParameters = new SubmitDownloadParameters();
            submitDownloadParameters.setCampaignIds(null);
            submitDownloadParameters.setDataScope(dataScopes);
            submitDownloadParameters.setDownloadEntities(entities);
            submitDownloadParameters.setFileType(DownloadFileType.CSV);
            submitDownloadParameters.setLastSyncTimeInUTC(null); 

            // Option A - Background Completion with BulkServiceManager
            // 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.

            outputStatusMessage("-----\nAwaiting Background Completion...");
            backgroundCompletionAsync(downloadParameters);

            // Alternatively we can use downloadEntitiesAsync if we want to work with the entities in memory.
            // If you enable this option the result file from BackgroundCompletionAsync will also be deleted
            // if written to the same working directory.
            outputStatusMessage("-----\nAwaiting Background Completion with DownloadEntitiesAsync...");
            List<BulkEntity> resultEntities = downloadEntitiesAsync(downloadParameters);

            // Option B - Submit and Download with BulkServiceManager
            // Submit the download request and then use the BulkDownloadOperation result to 
            // track status until the download is complete e.g. either using
            // trackAsync or getStatusAsync.

            outputStatusMessage("-----\nAwaiting Submit and Download...");
            submitTrackDownloadAsync(submitDownloadParameters);

            // Option C - Download Results with BulkServiceManager
            // If for any reason you have to resume from a previous application state, 
            // you can use an existing download request identifier and use it 
            // to download the result file. Use trackAsync to indicate that the application 
            // should wait to ensure that the download status is completed.

            // For example you might have previously retrieved a request ID using SubmitDownloadAsync.
            BulkDownloadOperation bulkDownloadOperation = BulkServiceManager.submitDownloadAsync(submitDownloadParameters, null).get();
            java.lang.String requestId = bulkDownloadOperation.getRequestId();

            // Given the request ID above, you can resume the workflow and download the bulk file.
            // The download request identifier is valid for two days. 
            // If you do not download the bulk file within two days, you must request it again.
            outputStatusMessage("-----\nAwaiting Download Results...");
            downloadResultsAsync(requestId);
        }
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        } 
        finally {
            if (downloadEntities != null){
                try {
                    downloadEntities.close();
                } 
                catch (IOException ex) {
                    outputStatusMessage(ex.getMessage());
                }
            }
        }
    }
    
    // Writes the specified entities to a local temporary file prior to upload.
    static List<BulkEntity> uploadEntitiesAsync(List<BulkEntity> uploadEntities) throws IOException, ExecutionException, InterruptedException 
    {
        // The system temp directory will be used if another working directory is not specified. If you are 
        // using a cloud service such as Microsoft 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.setWorkingDirectory(new File(FileDirectory));

        EntityUploadParameters entityUploadParameters = new EntityUploadParameters();
        entityUploadParameters.setEntities(uploadEntities);
        entityUploadParameters.setOverwriteResultFile(true);
        entityUploadParameters.setResultFileDirectory(new File(FileDirectory));
        entityUploadParameters.setResultFileName(ResultFileName);
        entityUploadParameters.setResponseMode(ResponseMode.ERRORS_AND_RESULTS);
        
        // The uploadEntitiesAsync method returns BulkEntityIterable, so the result file will not
        // be accessible e.g. for cleanupTempFiles until you iterate over the result and close the BulkEntityIterable instance.
        
        BulkEntityIterable tempEntities = BulkServiceManager.uploadEntitiesAsync(entityUploadParameters, null, null).get();
        
        ArrayList<BulkEntity> resultEntities = new ArrayList<BulkEntity>();
        for (BulkEntity entity : tempEntities) {
            resultEntities.add(entity);
        }
        
        tempEntities.close();
        
        // 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;
    }
    
    // Writes the specified entities to a local temporary file after download. 
    static List<BulkEntity> downloadEntitiesAsync(DownloadParameters downloadParameters) throws IOException, ExecutionException, InterruptedException 
    {
        // The system temp directory will be used if another working directory is not specified. If you are 
        // using a cloud service such as Microsoft 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.setWorkingDirectory(new File(FileDirectory));
        
        // The downloadEntitiesAsync method returns BulkEntityIterable, so the download file will not
        // be accessible e.g. for cleanupTempFiles until you iterate over the result and close the BulkEntityIterable instance.
        
        BulkEntityIterable tempEntities = BulkServiceManager.downloadEntitiesAsync(downloadParameters, null, null).get();
        
        ArrayList<BulkEntity> resultEntities = new ArrayList<BulkEntity>();
        for (BulkEntity entity : tempEntities) {
            resultEntities.add(entity);
        }
        
        tempEntities.close();
        
        // 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;
    }
    
    // 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.
    private static void backgroundCompletionAsync(DownloadParameters downloadParameters) 
        throws ExecutionException, InterruptedException, TimeoutException 
    {
        
        // You may optionally cancel the downloadFileAsync operation after a specified time interval. 
        File resultFile = BulkServiceManager.downloadFileAsync(downloadParameters, null).get(TimeoutInMilliseconds, TimeUnit.MILLISECONDS);

        outputStatusMessage(String.format("Download result file: %s", resultFile.getName()));
    }
    
    // Submit the download request and then use the BulkDownloadOperation result to 
    // track status until the download is complete using trackAsync.
    private static void submitTrackDownloadAsync(SubmitDownloadParameters submitDownloadParameters) 
        throws ExecutionException, InterruptedException, URISyntaxException, IOException, TimeoutException 
    {
        BulkDownloadOperation bulkDownloadOperation = BulkServiceManager.submitDownloadAsync(submitDownloadParameters, null).get();

        // You may optionally cancel the trackAsync operation after a specified time interval.
        BulkOperationStatus<DownloadStatus> downloadStatus = 
            bulkDownloadOperation.trackAsync(null).get(TimeoutInMilliseconds, TimeUnit.MILLISECONDS);
        
        File resultFile = bulkDownloadOperation.downloadResultFileAsync(
            new File(FileDirectory),
            ResultFileName,
            true, // Set this value to true if you want to decompress the ZIP file.
            true,  // Set this value true if you want to overwrite the named file.
            null).get();

        outputStatusMessage(String.format("Download result file: %s", resultFile.getName()));
    }
    
    // Submit the download request and then use the BulkDownloadOperation result to 
    // track status until the download is complete using getStatusAsync.
    private static void submitPollDownloadAsync(SubmitDownloadParameters submitDownloadParameters) 
        throws ExecutionException, InterruptedException, URISyntaxException, IOException, TimeoutException 
    {
        BulkDownloadOperation bulkDownloadOperation = BulkServiceManager.submitDownloadAsync(submitDownloadParameters, null).get();

    BulkOperationStatus<DownloadStatus> downloadStatus;
        
    for (int i = 0; i < 24; i++)
    {
        Thread.sleep(5000);
        downloadStatus = bulkDownloadOperation.getStatusAsync(null).get(TimeoutInMilliseconds, TimeUnit.MILLISECONDS);
        if (downloadStatus.getStatus() == DownloadStatus.COMPLETED)
        {
            break;
        }
    }

        File resultFile = bulkDownloadOperation.downloadResultFileAsync(
            new File(FileDirectory),
            ResultFileName,
            true, // Set this value to true if you want to decompress the ZIP file.
            true,  // Set this value true if you want to overwrite the named file.
            null).get();

        outputStatusMessage(String.format("Download result file: %s", resultFile.getName()));
    }
    
    // If for any reason you have to resume from a previous application state, 
    // you can use an existing download request identifier and use it 
    // to download the result file. Use trackAsync to indicate that the application 
    // should wait to ensure that the download status is completed.
    private static void downloadResultsAsync(java.lang.String requestId) 
        throws ExecutionException, InterruptedException, URISyntaxException, IOException, TimeoutException 
    {

        BulkDownloadOperation bulkDownloadOperation = new BulkDownloadOperation(requestId, authorizationData, API_ENVIRONMENT);

        bulkDownloadOperation.setStatusPollIntervalInMilliseconds(5000);

        // You can use trackAsync to poll until complete as shown here, 
        // or use custom polling logic with getStatusAsync.
        
        // You may optionally cancel the trackAsync operation after a specified time interval.
        BulkOperationStatus<DownloadStatus> downloadStatus = 
                        bulkDownloadOperation.trackAsync(null).get(TimeoutInMilliseconds, TimeUnit.MILLISECONDS);

        File resultFile = bulkDownloadOperation.downloadResultFileAsync(
            new File(FileDirectory),
            ResultFileName,
            true, // Set this value to true if you want to decompress the ZIP file
            true,  // Set this value true if you want to overwrite the named file.
            null).get();

        outputStatusMessage(String.format("Download result file: %s", resultFile.getName()));
        outputStatusMessage(String.format("Status: %s", downloadStatus.getStatus()));
        outputStatusMessage(String.format("TrackingId: %s", downloadStatus.getTrackingId()));
    }
}
<?php

use GuzzleHttp\Exception\GuzzleException;
use Microsoft\MsAds\Rest\ApiException;
use Microsoft\MsAds\Rest\Model\BulkService\DataScope;
use Microsoft\MsAds\Rest\Model\BulkService\DownloadCampaignsByAccountIdsRequest;
use Microsoft\MsAds\Rest\Model\BulkService\DownloadEntity;
use Microsoft\MsAds\Rest\Model\BulkService\DownloadFileType;
use Microsoft\MsAds\Rest\Model\BulkService\GetBulkDownloadStatusRequest;
use Microsoft\MsAds\Rest\Model\BulkService\GetBulkUploadStatusRequest;
use Microsoft\MsAds\Rest\Model\BulkService\GetBulkUploadUrlRequest;
use Microsoft\MsAds\Rest\Model\BulkService\ResponseMode;
use Microsoft\MsAds\Rest\Test\RestApiTestBase;

class BulkDownloadUploadTest extends RestApiTestBase
{
    // The full path to the bulk file.
    private static string $BulkFilePath = "c:\\dev\\bulk\\campaigns.zip";
    private static string $uploadFilePath = "c:\\dev\\bulk\\campaigns_upload.zip";

    // Confirm that the download folder exist; otherwise, exit.

    public static function setUpBeforeClass(): void
    {
        parent::setUpBeforeClass();

        $length = strrpos(self::$BulkFilePath, '\\');
        $folder = substr(self::$BulkFilePath, 0, $length);

        if (!is_dir($folder))
        {
            printf("The output folder, %s, does not exist.\r\nEnsure that the " .
                "folder exists and try again.", $folder);
            exit(1);
        }
    }

    /**
     * @throws ApiException
     */
    public function testDownloadCampaignsByAccountIds(): string
    {
        $request = new DownloadCampaignsByAccountIdsRequest();
        $request->setAccountIds([self::CUSTOMER_ACCOUNT_ID]);
        $request->setDataScope(DataScope::ENTITY_DATA);
        $request->setDownloadEntities([DownloadEntity::AD_GROUPS, DownloadEntity::CAMPAIGNS]);
        $request->setDownloadFileType(DownloadFileType::CSV);
        $request->setFormatVersion('6.0');
        $request->setLastSyncTimeInUTC(null);

        $response = self::$bulkServiceApi->downloadCampaignsByAccountIds($request);
        // The request ID will be used to poll for status before downloading the bulk file.

        $this->assertNotNull($response->getDownloadRequestId(), 'DownloadRequestId should not be null');
        return $response->getDownloadRequestId();
    }

    /**
     * @depends testDownloadCampaignsByAccountIds
     * @throws ApiException
     * @throws GuzzleException
     */
    public function testGetBulkDownloadStatus(string $downloadRequestId): string
    {
        // This sample polls every 30 seconds up to 5 minutes.
        // In production you may poll the status every 1 to 2 minutes for up to one hour.
        // If the call succeeds, stop polling. If the call or
        // download fails, the call throws a fault.
        $downloadSuccess = false;
        $waitTime = 5;

        for ($i = 0; $i < 10; $i++)
        {
            sleep($waitTime);

            // GetDownloadRequestStatus helper method calls the corresponding Bing Ads service operation
            // to get the download status.

            $request = new GetBulkDownloadStatusRequest();
            $request->setRequestId($downloadRequestId);

            $response = self::$bulkServiceApi->getBulkDownloadStatus($request);
            print("-----\r\nGetBulkDownloadStatus:\r\n");
            $requestStatus = $response->getRequestStatus();
            $resultFileUrl = $response->getResultFileUrl();
            printf("PercentComplete: %s\r\n", $response->getPercentComplete());
            printf("RequestStatus: %s\r\n", $requestStatus);
            printf("ResultFileUrl: %s\r\n", $resultFileUrl);

            if (($requestStatus != null) && ($requestStatus == "Completed"))
            {
                $downloadSuccess = true;
                break;
            }
        }

        if ($downloadSuccess)
        {
            // Download the file.
            printf("-----\r\nDownloading from %s...\r\n", $resultFileUrl);
            self::DownloadFile($resultFileUrl, self::$BulkFilePath);
        }
        else // Pending
        {
            self::fail("Download request failed, request ID: " . $downloadRequestId);
        }

        return $response->getResultFileUrl();
    }

    /**
     * @throws ApiException
     */
    public function testBulkUpload(): array
    {
        print("-----\r\nGetBulkUploadUrl:\r\n");
        $request = new GetBulkUploadUrlRequest();
        $request->setResponseMode(ResponseMode::ERRORS_AND_RESULTS);
        $request->setAccountId(self::CUSTOMER_ACCOUNT_ID); // Replace with actual account ID

        $response = self::$bulkServiceApi->getBulkUploadUrl($request);
        $uploadRequestId = $response->getRequestId();
        $uploadUrl = $response->getUploadUrl();
        printf("RequestId: %s\r\n", $uploadRequestId);
        printf("UploadUrl: %s\r\n", $uploadUrl);
        $this->assertNotNull($uploadRequestId, 'UploadRequestId should not be null');
        $this->assertNotNull($uploadUrl, 'UploadUrl should not be null');

        return [$uploadRequestId, $uploadUrl];
    }

    /**
     * @depends testBulkUpload
     * @throws GuzzleException
     */
    public function testUploadFile(array $uploadDetails): string
    {
        // You may unzip and update the downloaded bulk file or prepare a new file elsewhere.
        // Changes to the bulk file are not shown here.
        $uploadRequestId = $uploadDetails[0];
        $uploadUrl = $uploadDetails[1];
        printf("-----\r\nUploading file [%s] to %s...\r\n", self::$uploadFilePath, $uploadUrl);
        self::UploadFile(
            $uploadUrl,
            self::$uploadFilePath
        );

        return $uploadRequestId;
    }

    /**
     * @depends testUploadFile
     * @throws ApiException
     * @throws GuzzleException
     */
    public function testGetBulkUploadStatus(string $uploadRequestId): void
    {
        // This sample polls every 30 seconds up to 5 minutes.
        // In production you may poll the status every 1 to 2 minutes for up to one hour.
        // If the call succeeds, stop polling. If the call or
        // download fails, the call throws a fault.

        $uploadSuccess = false;
        $waitTime = 5;

        for ($i = 0; $i < 10; $i++) {
            sleep($waitTime);
            $request = new GetBulkUploadStatusRequest();
            $request->setRequestId($uploadRequestId);

            $response = self::$bulkServiceApi->getBulkUploadStatus($request);
            print("-----\r\nGetBulkUploadStatus:\r\n");
            $requestStatus = $response->getRequestStatus();
            $resultFileUrl = $response->getResultFileUrl();
            printf("PercentComplete: %s\r\n", $response->getPercentComplete());
            printf("RequestStatus: %s\r\n", $requestStatus);
            printf("ResultFileUrl: %s\r\n", $resultFileUrl);

            if (($requestStatus != null) && (($requestStatus == "Completed")
                    || ($requestStatus == "CompletedWithErrors")))
            {
                $uploadSuccess = true;
                break;
            }
        }

        if ($uploadSuccess)
        {
            // Download the file.
            printf("-----\r\nDownloading from %s...\r\n", $resultFileUrl);
            self::DownloadFile($resultFileUrl, self::$BulkFilePath);
        }
        else // Pending
        {
            self::fail("Upload request failed, request ID: " . $uploadRequestId);
        }

    }
}
import time
import os
from auth_helper import *
from openapi_client.models.bulk import *

# The full path to the bulk file
BULK_FILE_PATH = "c:\\dev\\bulk\\campaigns.zip"
UPLOAD_FILE_PATH = "c:\\dev\\bulk\\campaigns_upload.zip"

def main(authorization_data):
    try:
        # Confirm that the download folder exists
        folder = os.path.dirname(BULK_FILE_PATH)
        if not os.path.exists(folder):
            print(f"The output folder, {folder}, does not exist.")
            print("Ensure that the folder exists and try again.")
            return
        
        # Download campaigns by account IDs
        print("Requesting bulk download...")
        
        download_request = DownloadCampaignsByAccountIdsRequest(
            account_ids=[authorization_data.account_id],
            data_scope=DataScope.ENTITYDATA,
            download_entities=[DownloadEntity.ADGROUPS, DownloadEntity.CAMPAIGNS],
            download_file_type=DownloadFileType.CSV,
            format_version='6.0',
            last_sync_time_in_utc=None
        )
        
        download_response = bulk_service.download_campaigns_by_account_ids(
            download_campaigns_by_account_ids_request=download_request
        )
        
        download_request_id = download_response.DownloadRequestId
        
        if not download_request_id:
            print("DownloadRequestId should not be null")
            return
        
        print(f"Download Request ID: {download_request_id}")
        
        # Poll for download status
        print("\nPolling for download status...")
        
        download_success = False
        wait_time = 5
        result_file_url = None
        
        for i in range(10):
            time.sleep(wait_time)
            
            status_request = GetBulkDownloadStatusRequest(
                request_id=download_request_id
            )
            
            status_response = bulk_service.get_bulk_download_status(
                get_bulk_download_status_request=status_request
            )
            
            request_status = status_response.RequestStatus
            result_file_url = status_response.ResultFileUrl
            
            print(f"Attempt {i+1}:")
            print(f"  PercentComplete: {status_response.PercentComplete}")
            print(f"  RequestStatus: {request_status}")
            print(f"  ResultFileUrl: {result_file_url}")
            
            if request_status == "Completed":
                download_success = True
                break
        
        if download_success and result_file_url:
            print(f"\nDownloading file from {result_file_url}...")
            # In a real implementation, you would download the file here
            # For example, using requests library:
            # import requests
            # response = requests.get(result_file_url)
            # with open(BULK_FILE_PATH, 'wb') as f:
            #     f.write(response.content)
            print(f"File would be saved to: {BULK_FILE_PATH}")
        else:
            print(f"Download request failed or timed out. Request ID: {download_request_id}")
            return
        
        # Bulk Upload
        print("\n" + "="*50)
        print("Starting bulk upload...")
        
        get_upload_url_request = GetBulkUploadUrlRequest(
            response_mode=ResponseMode.ERRORSANDRESULTS,
            account_id=authorization_data.account_id
        )
        
        upload_url_response = bulk_service.get_bulk_upload_url(
            get_bulk_upload_url_request=get_upload_url_request
        )
        
        upload_request_id = upload_url_response.RequestId
        upload_url = upload_url_response.UploadUrl
        
        print(f"Upload Request ID: {upload_request_id}")
        print(f"Upload URL: {upload_url}")
        
        if not upload_request_id or not upload_url:
            print("UploadRequestId or UploadUrl should not be null")
            return
        
        # Upload the file
        print(f"\nUploading file {UPLOAD_FILE_PATH} to {upload_url}...")
        # In a real implementation, you would upload the file here
        # For example, using requests library with multipart upload:
        # import requests
        # with open(UPLOAD_FILE_PATH, 'rb') as f:
        #     files = {'payload': ('payload.zip', f, 'application/zip')}
        #     headers = {
        #         'DeveloperToken': DEVELOPER_TOKEN,
        #         'CustomerId': str(authorization_data.customer_id),
        #         'CustomerAccountId': str(authorization_data.account_id)
        #     }
        #     response = requests.post(upload_url, files=files, headers=headers)
        print("File upload would be performed here")
        
        # Poll for upload status
        print("\nPolling for upload status...")
        
        upload_success = False
        
        for i in range(10):
            time.sleep(wait_time)
            
            upload_status_request = GetBulkUploadStatusRequest(
                request_id=upload_request_id
            )
            
            upload_status_response = bulk_service.get_bulk_upload_status(
                get_bulk_upload_status_request=upload_status_request
            )
            
            request_status = upload_status_response.RequestStatus
            result_file_url = upload_status_response.ResultFileUrl
            
            print(f"Attempt {i+1}:")
            print(f"  PercentComplete: {upload_status_response.PercentComplete}")
            print(f"  RequestStatus: {request_status}")
            print(f"  ResultFileUrl: {result_file_url}")
            
            if request_status in ["Completed", "CompletedWithErrors"]:
                upload_success = True
                break
        
        if upload_success and result_file_url:
            print(f"\nDownloading result file from {result_file_url}...")
            print(f"Result file would be saved to: {BULK_FILE_PATH}")
        else:
            print(f"Upload request failed or timed out. Request ID: {upload_request_id}")
            
    except Exception as ex:
        print(f"Error occurred: {str(ex)}")

if __name__ == '__main__':
    print("Loading the web service client...")
    
    authorization_data = AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )
    
    authenticate(authorization_data)
    
    bulk_service = ServiceClient(
        service='BulkService',
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )
    
    main(authorization_data)

Siehe auch

Erste Schritte mit der Bing Ads-API