ภาษา
หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
ตัวอย่างนี้แสดงวิธีการดาวน์โหลดแคมเปญ กลุ่มโฆษณา และโฆษณาในไฟล์ .csv โดยใช้บริการเป็นกลุ่ม
เคล็ดลับ
ใช้ตัวเลือกภาษาในส่วนหัวของเอกสารประกอบเพื่อเลือก C#, Java, PHP หรือ Python
เมื่อต้องการรับการเข้าถึงและรีเฟรชโทเค็นสําหรับผู้ใช้ Microsoft Advertising ของคุณ และทําการเรียกใช้บริการครั้งแรกของคุณโดยใช้ Bing Ads API ให้ดูคู่มือเริ่มต้นใช้งานด่วน คุณจะต้องตรวจสอบคู่มือเริ่มต้นใช้งานและคําแนะนําสําหรับภาษาที่คุณต้องการ เช่น C#, Java, PHP และ Python
ไฟล์ที่สนับสนุนสําหรับตัวอย่าง C#, Java, PHP และ Python มีอยู่ที่ GitHub คุณสามารถโคลนแต่ละที่เก็บหรือนําส่วนย่อยไปใช้ใหม่ได้ตามต้องการ
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)