Edit

Geographical Locations Code Example

This example demonstrates how to download the comma separated value (CSV) file that contains geographical location information that can be used with Microsoft Advertising location targeting.

Tip

Use the language selector in the documentation header to choose C#, Java, Php, or Python.

To get access and refresh tokens for your Microsoft Advertising user and make your first service call using the Bing Ads API, see the Quick Start guide. You'll want to review the Get Started guide and walkthroughs for your preferred language e.g., C#, Java, Php, and Python.

Supporting files for C#, Java, Php, and Python examples are available at GitHub. You can clone each repository or repurpose snippets as needed.

using System;
using System.IO;
using System.Net;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to download the comma separated value (CSV) file that contains geographical location information 
    /// that can be used with Microsoft Advertising location targeting.
    /// </summary>
    public class GeographicalLocations : ExampleBase
    {
        // The full path to the geographical locations file.

        private const string LocalFile = @"c:\geolocations\geolocations.csv";

        // The language and locale of the geographical locations file available for download.
        // This example uses 'en' (English). Supported locales are 'zh-Hant' (Traditional Chinese), 'en' (English), 'fr' (French), 
        // 'de' (German), 'it' (Italian), 'pt-BR' (Portuguese - Brazil), and 'es' (Spanish). 

        private const string LanguageLocale = "en";

        // The latest supported file format version is 2.0. 

        private const string Version = "2.0";

        public override string Description
        {
            get { return "Geographical Locations | Campaign Management V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {

            Stream responseStream = null;
            FileStream fileStream = null;
            
            var fileInfo = new FileInfo(LocalFile);

            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

                CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
                    OutputStatusMessageDefault: this.OutputStatusMessage);
                CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                    authorizationData: authorizationData,
                    environment: environment);

                OutputStatusMessage("-----\nGetGeoLocationsFileUrl:");
                var getGeoLocationsFileUrlResponse = await CampaignManagementExampleHelper.GetGeoLocationsFileUrlAsync(
                    version: Version,
                    languageLocale: LanguageLocale);

                // Going forward you should track the date and time of the previous download,  
                // and compare it with the last modified time provided by the service.
                var previousSyncTimeUtc = new DateTime(2017, 8, 10, 0, 0, 0, DateTimeKind.Utc);

                var fileUrl = getGeoLocationsFileUrlResponse.FileUrl;
                var fileUrlExpiryTimeUtc = getGeoLocationsFileUrlResponse.FileUrlExpiryTimeUtc;
                var lastModifiedTimeUtc = getGeoLocationsFileUrlResponse.LastModifiedTimeUtc;

                OutputStatusMessage(string.Format("FileUrl: {0}", fileUrl));
                OutputStatusMessage(string.Format("FileUrlExpiryTimeUtc: {0}", fileUrlExpiryTimeUtc));
                OutputStatusMessage(string.Format("LastModifiedTimeUtc: {0}", lastModifiedTimeUtc));

                // Download the file if it was modified since the previous download.
                if (DateTime.Compare(previousSyncTimeUtc, lastModifiedTimeUtc) < 0)
                {
                    DownloadFile(fileUrl, LocalFile);
                }

            }
            // 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 Campaign Management service exceptions
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.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 (FaultException<Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> 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 (Exception ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
                if (responseStream != null) responseStream.Close();
            }
        }
                
        private void DownloadFile(string fileUrl, string localFile)
        {
            Stream responseStream = null;
            FileStream fileStream = null;

            var fileInfo = new FileInfo(localFile);

            try
            {
                var request = (HttpWebRequest)WebRequest.Create(fileUrl);
                request.AutomaticDecompression = DecompressionMethods.GZip;
                
                var response = (HttpWebResponse)request.GetResponse();
                
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    fileStream = new FileStream(fileInfo.FullName, FileMode.Create);
                    responseStream = response.GetResponseStream();
                    if (responseStream != null)
                    {
                        responseStream.CopyTo(fileStream);
                    }
                    OutputStatusMessage(string.Format("Downloaded the file to {0}.", localFile));
                }
            }
            catch (WebException e)
            {
                if (e != null && e.Response != null)
                {
                    OutputStatusMessage("Unexpected status code = " + ((HttpWebResponse)e.Response).StatusCode);
                }
                else
                {
                    OutputStatusMessage("Unexpected Web Exception " + e.Message);
                }
            }
            catch (IOException ex)
            {
                OutputStatusMessage(ex.Message);
            }
            finally
            {
                if (fileStream != null) fileStream.Close();
                if (responseStream != null) responseStream.Close();
            }
        }
    }
}
package com.microsoft.bingads.examples.v13;

import java.net.*;
import java.io.*;
import java.util.Calendar;
import java.util.TimeZone;

import com.microsoft.bingads.*;
import com.microsoft.bingads.v13.campaignmanagement.*;

/**
 * This example demonstrates how to download the comma separated value (CSV) file that contains geographical location information 
 * that can be used with Bing Ads location targeting.
 */
    
public class GeographicalLocations extends ExampleBase {
    
    // The full path to the geographical locations file.

    private static final java.lang.String LOCAL_FILE= "c:\\geolocations\\geolocations.csv";

    // The language and locale of the geographical locations file available for download.
    // This example uses 'en' (English). Supported locales are 'zh-Hant' (Traditional Chinese), 'en' (English), 'fr' (French), 
    // 'de' (German), 'it' (Italian), 'pt-BR' (Portuguese - Brazil), and 'es' (Spanish). 

    private static final java.lang.String LANGUAGE_LOCALE = "en";
    
    // The latest supported file format version is 2.0. 

    private static final java.lang.String VERSION= "2.0";

    public static void main(java.lang.String[] args) {
    
        try
        {
            authorizationData = getAuthorizationData(); 

            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                        authorizationData, 
                        API_ENVIRONMENT,
                        ICampaignManagementService.class);
            
            outputStatusMessage("-----\nGetGeoLocationsFileUrl:");
            GetGeoLocationsFileUrlResponse getGeoLocationsFileUrlResponse = CampaignManagementExampleHelper.getGeoLocationsFileUrl(
                    VERSION, 
                    LANGUAGE_LOCALE);

            // Going forward you should track the date and time of the previous download,  
            // and compare it with the last modified time provided by the service.            
            Calendar previousSyncTimeUtc = Calendar.getInstance();
            previousSyncTimeUtc.setTimeZone(TimeZone.getTimeZone("GMT"));
            previousSyncTimeUtc.set(2018, 4, 31, 19, 25, 36); // 2018-05-31T19:25:36Z

            java.lang.String fileUrl = getGeoLocationsFileUrlResponse.getFileUrl();
            Calendar fileUrlExpiryTimeUtc = getGeoLocationsFileUrlResponse.getFileUrlExpiryTimeUtc();
            Calendar lastModifiedTimeUtc = getGeoLocationsFileUrlResponse.getLastModifiedTimeUtc();

            outputStatusMessage(String.format("PreviousSyncTimeUtc: %s", previousSyncTimeUtc.getTime().toString()));
            outputStatusMessage(String.format("FileUrl: %s", fileUrl));
            outputStatusMessage(String.format("FileUrlExpiryTimeUtc: %s", fileUrlExpiryTimeUtc.getTime().toString()));
            outputStatusMessage(String.format("LastModifiedTimeUtc: %s", lastModifiedTimeUtc.getTime().toString()));

            // Download the file if it was modified since the previous download.
            if (lastModifiedTimeUtc.compareTo(previousSyncTimeUtc) > 0)
            {
                downloadFile(fileUrl, LOCAL_FILE);
            }            
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }    
    
    // Downloads a file from the remote file URL to a local file URL.
    
    static void downloadFile(java.lang.String fileUrl, java.lang.String localFile) 
    {
        HttpURLConnection connection = null;
        BufferedInputStream reader = null;
        BufferedOutputStream writer = null;
        
        try {
            URL url = new URL(fileUrl);
            connection = (HttpURLConnection) url.openConnection();

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) 
            {
                outputStatusMessage(String.format("Downloaded the geographical locations to %s.", localFile));
                reader = new BufferedInputStream(connection.getInputStream());
                writer = new BufferedOutputStream(new FileOutputStream(localFile));

                final int bufferSize = 100 * 1024;
                byte[] buffer = new byte[bufferSize];
                int count = 0;            

                while ((count = reader.read(buffer)) != -1)
                {
                    writer.write(buffer, 0, count);
                }
            } 
            else
            {
                outputStatusMessage(String.format("HTTP Response Code: %s", connection.getResponseCode()));  
                outputStatusMessage(String.format("HTTP Response Message: %s", connection.getResponseMessage()));  
            } 
        } 
        catch (IOException ex) {
            outputStatusMessage(String.format("IO Exception encountered: %s", ex.getMessage()));
        } 
        catch (Exception ex) {
            outputStatusMessage(String.format("Error encountered: %s", ex.getMessage()));
        } 
        finally {
            try {
                if (reader != null) reader.close();
                if (writer != null)
                {
                    writer.flush();
                    writer.close();
                }
            } 
            catch (IOException ex) {
                outputStatusMessage(String.format("IO Exception encountered: %s", ex.getMessage()));
            }
        }  
    }
}
<?php

namespace Microsoft\BingAds\Samples\V13;

// For more information about installing and using the Bing Ads PHP SDK, 
// see https://go.microsoft.com/fwlink/?linkid=838593.

require_once __DIR__ . "/../vendor/autoload.php";

include __DIR__ . "/AuthHelper.php";
include __DIR__ . "/CampaignManagementExampleHelper.php";

use SoapVar;
use SoapFault;
use Exception;
use DateTime;

// Specify the Microsoft\BingAds\Auth classes that will be used.
use Microsoft\BingAds\Auth\ServiceClient;
use Microsoft\BingAds\Auth\ServiceClientType;

// Specify the Microsoft\BingAds\Samples classes that will be used.
use Microsoft\BingAds\Samples\V13\AuthHelper;
use Microsoft\BingAds\Samples\V13\CampaignManagementExampleHelper;

// The full path where you want to download the geographical locations file.

$GLOBALS['LocalFile'] = "c:\\geolocations\\geolocations.csv";

// The temporary location of the download file.

$GLOBALS['TempFile'] = "c:\\geolocations\\temp.csv";

// The latest supported file format version is 2.0. 

$Version = "2.0";

// The language and locale of the geographical locations file available for download.
// This example uses 'en' (English). Supported locales are 'zh-Hant' (Traditional Chinese), 'en' (English), 'fr' (French), 
// 'de' (German), 'it' (Italian), 'pt-BR' (Portuguese - Brazil), and 'es' (Spanish). 

$LanguageLocale = "en";

try
{
    // Authenticate user credentials and set the account ID for the sample.  
    AuthHelper::Authenticate();

    date_default_timezone_set('UTC');

    // Going forward you should track the date and time of the previous download,  
    // and compare it with the last modified time provided by the service.
    $previousSyncTimeUtc = new DateTime('2017-08-10T00:00:00-00:00');
    
    print("-----\r\nGetGeoLocationsFileUrl:\r\n");
    $getGeoLocationsFileUrlResponse = CampaignManagementExampleHelper::GetGeoLocationsFileUrl(
        $Version, 
        $LanguageLocale
    );

    $fileUrl = $getGeoLocationsFileUrlResponse->FileUrl;
    $fileUrlExpiryTimeUtc = $getGeoLocationsFileUrlResponse->FileUrlExpiryTimeUtc;
    $lastModifiedTimeUtc = $getGeoLocationsFileUrlResponse->LastModifiedTimeUtc;

    printf("FileUrl: %s\r\n", $fileUrl);
    printf("FileUrlExpiryTimeUtc: %s\r\n", $fileUrlExpiryTimeUtc);
    printf("LastModifiedTimeUtc: %s\r\n", $lastModifiedTimeUtc);
    
    // Download the file if it was modified since the previous download.
    if($previousSyncTimeUtc < new DateTime($lastModifiedTimeUtc))
    {
        printf("Downloading the file locally: %s\r\n", 
            $GLOBALS['LocalFile']
        );
        DownloadFile($fileUrl);
    }
    else
    {
        printf("The file has not been modified since your previous sync time (%s).\r\n", 
            $previousSyncTimeUtc->format('Y-m-d\TH:i:se')
        );
    }
}
catch (SoapFault $e)
{
    printf("-----\r\nFault Code: %s\r\nFault String: %s\r\nFault Detail: \r\n", $e->faultcode, $e->faultstring);
    var_dump($e->detail);
    print "-----\r\nLast SOAP request/response:\r\n";
    print $GLOBALS['Proxy']->GetWsdl() . "\r\n";
    print $GLOBALS['Proxy']->GetService()->__getLastRequest()."\r\n";
    print $GLOBALS['Proxy']->GetService()->__getLastResponse()."\r\n";
}
catch (Exception $e)
{
    // Ignore fault exceptions that we already caught.
    if ($e->getPrevious())
    { ; }
    else
    {
        print $e->getCode()." ".$e->getMessage()."\r\n";
        print $e->getTraceAsString()."\r\n";
    }
}

function DownloadFile($fileUrl){
    $ch = curl_init($fileUrl);
    $fileHandle = fopen($GLOBALS['TempFile'], 'w+');

    curl_setopt($ch, CURLOPT_FILETIME, true); 
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    curl_setopt($ch, CURLOPT_FILE, $fileHandle); 
    
    curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);

    $response = curl_exec($ch); 

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);     
 
    curl_close($ch);
    fclose($fileHandle);
    
    if ($httpCode == 200)
    {
        printf("Downloaded the geographical locations to %s.\r\n", $GLOBALS['LocalFile']);
        rename($GLOBALS['TempFile'], $GLOBALS['LocalFile']);
    }
    else
    {
        printf("The geographical locations file was not successfully downloaded.\r\n");
        unlink($GLOBALS['TempFile']);
    }
}
import os
from datetime import datetime, timezone
from auth_helper import *
from openapi_client.models.campaign import *
import requests


# File paths for downloading geographical locations file
LOCAL_FILE = os.path.join(os.path.expanduser("~"), "Downloads", "geolocations.csv")
VERSION = "2.0"
LANGUAGE_LOCALE = "en"


def download_file(url, file_path):
    """
    Download a file from the given URL to the specified file path.
    
    Args:
        url: The URL to download from
        file_path: The local path to save the file
    """
    print(f"Downloading the file locally: {file_path}")
    
    response = requests.get(url, stream=True)
    
    if response.status_code == 200:
        with open(file_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        print(f"Downloaded the file to {file_path}")
    else:
        print(f"The file was not successfully downloaded. HTTP Code {response.status_code}")
        raise Exception(f"Download failed with status code {response.status_code}")


def main(authorization_data):
    try:
        # Get the geographical locations file URL
        print("Getting geographical locations file URL...")
        
        get_geo_locations_request = GetGeoLocationsFileUrlRequest(
            version=VERSION,
            language_locale=LANGUAGE_LOCALE
        )
        
        get_geo_locations_response = campaign_service.get_geo_locations_file_url(
            get_geo_locations_file_url_request=get_geo_locations_request
        )
        
        file_url = get_geo_locations_response.FileUrl
        file_url_expiry_time_utc = get_geo_locations_response.FileUrlExpiryTimeUtc
        last_modified_time_utc = get_geo_locations_response.LastModifiedTimeUtc
        
        print(f"FileUrl: {file_url}")
        print(f"FileUrlExpiryTimeUtc: {file_url_expiry_time_utc}")
        print(f"LastModifiedTimeUtc: {last_modified_time_utc}")
        
        # Download the geographical locations file
        print("\nDownloading geographical locations file...")
        
        # Set a previous sync time for comparison
        # You can modify this to your actual previous sync time
        previous_sync_time_utc = datetime(2017, 8, 10, 0, 0, 0, tzinfo=timezone.utc)
        
        # Parse the last modified time
        if isinstance(last_modified_time_utc, str):
            last_modified_datetime = datetime.fromisoformat(last_modified_time_utc.replace('Z', '+00:00'))
        else:
            last_modified_datetime = last_modified_time_utc
        
        # Ensure both datetimes are timezone-aware for comparison
        if last_modified_datetime.tzinfo is None:
            last_modified_datetime = last_modified_datetime.replace(tzinfo=timezone.utc)
        
        # Only download if the file has been modified since the previous sync
        if last_modified_datetime > previous_sync_time_utc:
            download_file(file_url, LOCAL_FILE)
            print(f"\nSuccessfully downloaded geographical locations file to {LOCAL_FILE}")
        else:
            print(f"\nThe file has not been modified since your previous sync time ({previous_sync_time_utc.isoformat()})")
        
    except Exception as ex:
        print(f"Error occurred: {str(ex)}")
        import traceback
        traceback.print_exc()


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)
    
    campaign_service = ServiceClient(
        service='CampaignManagementService',
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )
    
    main(authorization_data)

See Also

Get Started with the Bing Ads API