Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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)