Conversion Goals Code Example

This example demonstrates how to manage UET tags and conversion goals.

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.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds;

namespace BingAdsExamplesLibrary.V13
{
    /// <summary>
    /// How to manage UET tags and conversion goals.
    /// </summary>
    public class ConversionGoals : ExampleBase
    {
        public override string Description
        {
            get { return "UET Tags and Conversion Goals | Campaign Management V13"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;

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

                // Before you can track conversions or target audiences using a remarketing list 
                // you need to create a UET tag, and then add the UET tag tracking code to every page of your website.
                // For more information, please see Universal Event Tracking at https://go.microsoft.com/fwlink/?linkid=829965.

                // First you should call the GetUetTagsByIds operation to check whether a tag has already been created. 
                // You can leave the TagIds element null or empty to request all UET tags available for the customer.

                OutputStatusMessage("-----\nGetUetTagsByIds:");
                var getUetTagsByIdsResponse = (await CampaignManagementExampleHelper.GetUetTagsByIdsAsync(
                    tagIds: null));
                var uetTags = getUetTagsByIdsResponse.UetTags.ToArray();
                BatchError[] uetTagErrors = getUetTagsByIdsResponse.PartialErrors.ToArray();
                OutputStatusMessage("UetTags:");
                CampaignManagementExampleHelper.OutputArrayOfUetTag(uetTags);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(uetTagErrors);

                // If you do not already have a UET tag that can be used, or if you need another UET tag, 
                // call the AddUetTags service operation to create a new UET tag. If the call is successful, 
                // the tracking script that you should add to your website is included in a corresponding 
                // UetTag within the response message. 

                if (uetTags == null || uetTags.Length < 1)
                {
                    var uetTag = new UetTag
                    {
                        Description = "My First Uet Tag",
                        Name = "New Uet Tag",
                    };
                    OutputStatusMessage("-----\nAddUetTags:");
                    var addUetTagsResponse = await CampaignManagementExampleHelper.AddUetTagsAsync(
                        uetTags: uetTags);
                    uetTags = addUetTagsResponse.UetTags.ToArray();
                    uetTagErrors = addUetTagsResponse.PartialErrors.ToArray();
                    OutputStatusMessage("UetTags:");
                    CampaignManagementExampleHelper.OutputArrayOfUetTag(uetTags);
                    OutputStatusMessage("PartialErrors:");
                    CampaignManagementExampleHelper.OutputArrayOfBatchError(uetTagErrors);
                }

                if (uetTags == null || uetTags.Length < 1)
                {
                    OutputStatusMessage(
                        string.Format("You do not have any UET tags registered for CustomerId {0}.", authorizationData.CustomerId)
                    );
                    return;
                }

                // After you retreive the tracking script from the AddUetTags or GetUetTagsByIds operation, 
                // the next step is to add the UET tag tracking code to your website.
                // We will use the same UET tag for the remainder of this example.

                var tagId = uetTags[0].Id;                               
                
                // Add conversion goals that depend on the UET Tag Id retreived above.
                // Please note that you cannot delete conversion goals. If you want to stop 
                // tracking conversions for the goal, you can set the goal status to Paused.

                var conversionGoals = new ConversionGoal[]
                {
                    new DurationGoal
                    {
                        ConversionWindowInMinutes = 30,
                        CountType = ConversionGoalCountType.All,
                        MinimumDurationInSeconds = 60,
                        Name = "My Duration Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        Scope = EntityScope.Account,
                        Status = ConversionGoalStatus.Active,
                        TagId = tagId,
                    },
                    new EventGoal
                    {
                        GoalCategory = ConversionGoalCategory.Purchase,
                        // The type of user interaction you want to track.
                        ActionExpression = "play",
                        ActionOperator = ExpressionOperator.Contains,
                        // The category of event you want to track. 
                        CategoryExpression = "video",
                        CategoryOperator = ExpressionOperator.Contains,
                        ConversionWindowInMinutes = 30,
                        CountType = ConversionGoalCountType.All,
                        // The name of the element that caused the action.
                        LabelExpression = "trailer",
                        LabelOperator = ExpressionOperator.Contains,
                        Name = "My Event Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        Scope = EntityScope.Account,
                        Status = ConversionGoalStatus.Active,
                        TagId = tagId,
                        // A numerical value associated with that event. 
                        // Could be length of the video played etc.
                        Value = 5.00m,
                        ValueOperator = ValueOperator.Equals,
                    },
                    new PagesViewedPerVisitGoal
                    {
                        ConversionWindowInMinutes = 30,
                        CountType = ConversionGoalCountType.All,
                        MinimumPagesViewed = 5,
                        Name = "My Pages Viewed Per Visit Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        Scope = EntityScope.Account,
                        Status = ConversionGoalStatus.Active,
                        TagId = tagId,
                    },
                    new UrlGoal
                    {
                        GoalCategory = ConversionGoalCategory.Purchase,
                        ConversionWindowInMinutes = 30,
                        CountType = ConversionGoalCountType.All,
                        Name = "My Url Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        Scope = EntityScope.Account,
                        Status = ConversionGoalStatus.Active,
                        TagId = tagId,
                        UrlExpression = "contoso",
                        UrlOperator = ExpressionOperator.Contains
                    },
                    new AppInstallGoal
                    {
                        // You must provide a valid app platform and app store identifier, 
                        // otherwise this goal will not be added successfully. 
                        AppPlatform = "Windows",
                        AppStoreId = "AppStoreIdGoesHere",
                        ConversionWindowInMinutes = 30,
                        CountType = ConversionGoalCountType.All,
                        Name = "My App Install Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        // Account scope is not supported for app install goals. You can
                        // set scope to Customer or don't set it for the same result.
                        Scope = EntityScope.Customer,
                        Status = ConversionGoalStatus.Active,
                        // The TagId is inherited from the ConversionGoal base class,
                        // however, App Install goals do not use a UET tag.
                        TagId = null,
                    },
                };

                OutputStatusMessage("-----\nAddConversionGoals:");
                var addConversionGoalsResponse = await CampaignManagementExampleHelper.AddConversionGoalsAsync(
                    conversionGoals: conversionGoals);
                var goalIds = addConversionGoalsResponse.ConversionGoalIds.ToArray();
                BatchError[] conversionGoalErrors = addConversionGoalsResponse.PartialErrors.ToArray();
                OutputStatusMessage("ConversionGoalIds:");
                CampaignManagementExampleHelper.OutputArrayOfLong(goalIds);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(conversionGoalErrors);

                // Find the conversion goals that were added successfully. 

                List<long> conversionGoalIds = GetNonNullableIds(goalIds);

                var conversionGoalTypes =
                    ConversionGoalType.AppInstall |
                    ConversionGoalType.Duration |
                    ConversionGoalType.Event |
                    ConversionGoalType.PagesViewedPerVisit |
                    ConversionGoalType.Url;

                OutputStatusMessage("-----\nGetConversionGoalsByIds:");
                var getConversionGoalsResponse =  (await CampaignManagementExampleHelper.GetConversionGoalsByIdsAsync(
                        conversionGoalIds: conversionGoalIds,
                        conversionGoalTypes: conversionGoalTypes,
                        returnAdditionalFields: ConversionGoalAdditionalField.ViewThroughConversionWindowInMinutes));
                var getConversionGoals = getConversionGoalsResponse.ConversionGoals;
                conversionGoalErrors = getConversionGoalsResponse.PartialErrors.ToArray();
                OutputStatusMessage("ConversionGoals:");
                CampaignManagementExampleHelper.OutputArrayOfConversionGoal(getConversionGoals);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(conversionGoalErrors);

                // Update the conversion goals

                var updateConversionGoals = new ConversionGoal[]
                {
                    new DurationGoal
                    {
                        ConversionWindowInMinutes = 60,
                        CountType = ConversionGoalCountType.Unique,
                        // You can change the conversion goal type e.g. in this example an event goal
                        // had been created above at index 1. Now we are using the returned identifier
                        // at index 1 to update the type from EventGoal to DurationGoal.
                        Id = conversionGoalIds[1],
                        MinimumDurationInSeconds = 120,
                        Name = "My Updated Duration Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 10.00m,
                            CurrencyCode = null
                        },
                        // The Scope cannot be updated, even if you update the goal type.
                        // You can either send the same value or leave Scope empty.
                        Scope = EntityScope.Account,
                        Status = ConversionGoalStatus.Paused,
                        // You can update the tag as needed. In this example we will explicitly use the same UET tag.
                        // To keep the UET tag unchanged, you can also leave this element nil or empty.
                        TagId = tagId,
                    },
                    new EventGoal
                    {
                        // For both add and update conversion goal operations, you must include one or more  
                        // of the following events: 
                        // ActionExpression, CategoryExpression, LabelExpression, or Value.                        
                        // For example if you do not include ActionExpression during update, 
                        // any existing ActionOperator and ActionExpression settings will be deleted.
                        ActionExpression = null,
                        ActionOperator = null,
                        CategoryExpression = "video",
                        CategoryOperator = ExpressionOperator.Equals,
                        Id = conversionGoalIds[0],
                        // You cannot update the operator unless you also include the expression.
                        // The following attempt to update LabelOperator will result in an error.
                        LabelExpression = null,
                        LabelOperator = ExpressionOperator.Equals,
                        Name = "My Updated Event Goal",
                        Revenue = new ConversionGoalRevenue
                        {
                            Type = ConversionGoalRevenueType.FixedValue,
                            Value = 5.00m,
                            CurrencyCode = null
                        },
                        // You must specify the previous settings unless you want
                        // them replaced during the update conversion goal operation.
                        Value = 5.00m,
                        ValueOperator = ValueOperator.Equals,
                    },
                    new PagesViewedPerVisitGoal
                    {
                        Id = conversionGoalIds[2],
                        Name = "My Updated Pages Viewed Per Visit Goal",
                        // When updating a conversion goal, if the Revenue element is nil or empty then none 
                        // of the nested properties will be updated. However, if this element is not nil or empty 
                        // then you are effectively replacing any existing revenue properties. For example to delete 
                        // any previous revenue settings, set the Revenue element to an empty ConversionGoalRevenue object.
                        Revenue = new ConversionGoalRevenue(),
                    },
                    new UrlGoal
                    {
                        Id = conversionGoalIds[3],
                        Name = "My Updated Url Goal" + DateTime.UtcNow,
                        // If not specified during update, the previous Url settings are retained.
                        // If the expression is set, then the operator must also be set, and vice versa.
                        UrlExpression = "contoso",
                        UrlOperator = ExpressionOperator.BeginsWith
                    }
                };

                OutputStatusMessage("-----\nUpdateConversionGoals:");
                var updateConversionGoalsResponse = await CampaignManagementExampleHelper.UpdateConversionGoalsAsync(
                    conversionGoals: updateConversionGoals);
                conversionGoalErrors = updateConversionGoalsResponse.PartialErrors.ToArray();
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(conversionGoalErrors);

                OutputStatusMessage("-----\nGetConversionGoalsByIds:");
                getConversionGoals = (await CampaignManagementExampleHelper.GetConversionGoalsByIdsAsync(
                        conversionGoalIds: conversionGoalIds, 
                        conversionGoalTypes: conversionGoalTypes,
                        returnAdditionalFields: ConversionGoalAdditionalField.ViewThroughConversionWindowInMinutes)).ConversionGoals;
                getConversionGoals = getConversionGoalsResponse.ConversionGoals;
                conversionGoalErrors = getConversionGoalsResponse.PartialErrors.ToArray();
                OutputStatusMessage("ConversionGoals:");
                CampaignManagementExampleHelper.OutputArrayOfConversionGoal(getConversionGoals);
                OutputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.OutputArrayOfBatchError(conversionGoalErrors);
            }
            // 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 ConversionGoal 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);
            }
        }
    }
}
package com.microsoft.bingads.examples.v13;

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

import java.util.ArrayList;

public class ConversionGoals extends ExampleBase {

    public static void main(java.lang.String[] args) {
     
        try
        {
            authorizationData = getAuthorizationData();
             
            CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
                        authorizationData, 
                        API_ENVIRONMENT,
                        ICampaignManagementService.class);

            // Before you can track conversions or target audiences using a remarketing list 
            // you need to create a UET tag, and then add the UET tag tracking code to every page of your website.
            // For more information, please see Universal Event Tracking at https://go.microsoft.com/fwlink/?linkid=829965.

            // First you should call the GetUetTagsByIds operation to check whether a tag has already been created. 
            // You can leave the TagIds element null or empty to request all UET tags available for the customer.

            outputStatusMessage("-----\nGetUetTagsByIds:");
            GetUetTagsByIdsResponse getUetTagsByIdsResponse = CampaignManagementExampleHelper.getUetTagsByIds(
                    null);
            ArrayOfUetTag uetTags = getUetTagsByIdsResponse.getUetTags();
            ArrayOfBatchError uetTagErrors = getUetTagsByIdsResponse.getPartialErrors();
            outputStatusMessage("UetTags:");
            CampaignManagementExampleHelper.outputArrayOfUetTag(uetTags);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(uetTagErrors);

            // If you do not already have a UET tag that can be used, or if you need another UET tag, 
            // call the AddUetTags service operation to create a new UET tag. If the call is successful, 
            // the tracking script that you should add to your website is included in a corresponding 
            // UetTag within the response message.  

            if (uetTags == null || uetTags.getUetTags().size() < 1)
            {
                ArrayOfUetTag addUetTags = new ArrayOfUetTag();
                UetTag uetTag = new UetTag();
                uetTag.setDescription("My First Uet Tag");
                uetTag.setName("New Uet Tag");
                addUetTags.getUetTags().add(uetTag);
                        
                outputStatusMessage("-----\nAddUetTags:");
                AddUetTagsResponse addUetTagsResponse = CampaignManagementExampleHelper.addUetTags(addUetTags);
                uetTags = addUetTagsResponse.getUetTags();
                uetTagErrors = addUetTagsResponse.getPartialErrors();
                outputStatusMessage("UetTags:");
                CampaignManagementExampleHelper.outputArrayOfUetTag(uetTags);
                outputStatusMessage("PartialErrors:");
                CampaignManagementExampleHelper.outputArrayOfBatchError(uetTagErrors);
            }

            if (uetTags == null || uetTags.getUetTags().size() < 1)
            {
                outputStatusMessage(String.format(
                    "You do not have any UET tags registered for CustomerId {0}.", 
                    authorizationData.getCustomerId())
                );
                return;
            }

            // After you retreive the tracking script from the AddUetTags or GetUetTagsByIds operation, 
            // the next step is to add the UET tag tracking code to your website.
            // We will use the same UET tag for the remainder of this example.

            java.lang.Long tagId = uetTags.getUetTags().get(0).getId();
            
            // Add conversion goals that depend on the UET Tag Id retreived above.
            // Please note that you cannot delete conversion goals. If you want to stop 
            // tracking conversions for the goal, you can set the goal status to Paused.

            ArrayOfConversionGoal addConversionGoals = new ArrayOfConversionGoal();
            
            DurationGoal addDurationGoal = new DurationGoal();
            addDurationGoal.setConversionWindowInMinutes(30);
            addDurationGoal.setCountType(ConversionGoalCountType.ALL);
            addDurationGoal.setMinimumDurationInSeconds(60);
            addDurationGoal.setName("My Duration Goal");
            ConversionGoalRevenue addDurationGoalRevenue = new ConversionGoalRevenue();
            addDurationGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            addDurationGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            addDurationGoalRevenue.setCurrencyCode(null);
            addDurationGoal.setRevenue(addDurationGoalRevenue);
            addDurationGoal.setScope(EntityScope.ACCOUNT);
            addDurationGoal.setStatus(ConversionGoalStatus.ACTIVE);
            addDurationGoal.setTagId(tagId);
            addConversionGoals.getConversionGoals().add(addDurationGoal);
            
            EventGoal addEventGoal = new EventGoal();
            addEventGoal.setGoalCategory(ConversionGoalCategory.PURCHASE);
            // The type of user interaction you want to track.
            addEventGoal.setActionExpression("play");
            addEventGoal.setActionOperator(ExpressionOperator.CONTAINS);
            // The category of event you want to track. 
            addEventGoal.setCategoryExpression("video");
            addEventGoal.setCategoryOperator(ExpressionOperator.CONTAINS);
            addEventGoal.setConversionWindowInMinutes(30);
            addEventGoal.setCountType(ConversionGoalCountType.ALL);
            // The name of the element that caused the action.
            addEventGoal.setLabelExpression("trailer");
            addEventGoal.setLabelOperator(ExpressionOperator.CONTAINS);
            addEventGoal.setName("My Event Goal");
            ConversionGoalRevenue addEventGoalRevenue = new ConversionGoalRevenue();
            addEventGoalRevenue.setType(ConversionGoalRevenueType.VARIABLE_VALUE);
            addEventGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            addEventGoalRevenue.setCurrencyCode(null);
            addEventGoal.setRevenue(addEventGoalRevenue);
            addEventGoal.setScope(EntityScope.ACCOUNT);
            addEventGoal.setStatus(ConversionGoalStatus.ACTIVE);
            addEventGoal.setTagId(tagId);
            // A numerical value associated with that event. 
            // Could be length of the video played etc.
            addEventGoal.setValue(new java.math.BigDecimal(5.00));
            addEventGoal.setValueOperator(ValueOperator.EQUALS);
            addConversionGoals.getConversionGoals().add(addEventGoal);
            
            PagesViewedPerVisitGoal addPagesViewedPerVisitGoal = new PagesViewedPerVisitGoal();
            addPagesViewedPerVisitGoal.setConversionWindowInMinutes(30);
            addPagesViewedPerVisitGoal.setCountType(ConversionGoalCountType.ALL);
            addPagesViewedPerVisitGoal.setMinimumPagesViewed(5);
            addPagesViewedPerVisitGoal.setName("My Pages Viewed Per Visit Goal");
            ConversionGoalRevenue addPagesViewedPerVisitGoalRevenue = new ConversionGoalRevenue();
            addPagesViewedPerVisitGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            addPagesViewedPerVisitGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            addPagesViewedPerVisitGoalRevenue.setCurrencyCode(null);
            addPagesViewedPerVisitGoal.setRevenue(addPagesViewedPerVisitGoalRevenue);
            addPagesViewedPerVisitGoal.setScope(EntityScope.ACCOUNT);
            addPagesViewedPerVisitGoal.setStatus(ConversionGoalStatus.ACTIVE);
            addPagesViewedPerVisitGoal.setTagId(tagId);
            addConversionGoals.getConversionGoals().add(addPagesViewedPerVisitGoal);
            
            UrlGoal addUrlGoal = new UrlGoal();
            addUrlGoal.setGoalCategory(ConversionGoalCategory.PURCHASE);
            addUrlGoal.setConversionWindowInMinutes(30);
            addUrlGoal.setCountType(ConversionGoalCountType.ALL);
            addUrlGoal.setName("My Url Goal");
            ConversionGoalRevenue addUrlGoalRevenue = new ConversionGoalRevenue();
            addUrlGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            addUrlGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            addUrlGoalRevenue.setCurrencyCode(null);
            addUrlGoal.setRevenue(addUrlGoalRevenue);
            addUrlGoal.setScope(EntityScope.ACCOUNT);
            addUrlGoal.setStatus(ConversionGoalStatus.ACTIVE);
            addUrlGoal.setUrlExpression("contoso");
            addUrlGoal.setUrlOperator(ExpressionOperator.CONTAINS);
            addUrlGoal.setTagId(tagId);
            addConversionGoals.getConversionGoals().add(addUrlGoal);
            
            AppInstallGoal addAppInstallGoal = new AppInstallGoal();
            // You must provide a valid app platform and app store identifier, 
            // otherwise this goal will not be added successfully. 
            addAppInstallGoal.setAppPlatform("Windows");
            addAppInstallGoal.setAppStoreId("AppStoreIdGoesHere");
            addAppInstallGoal.setConversionWindowInMinutes(30);
            addAppInstallGoal.setCountType(ConversionGoalCountType.ALL);
            addAppInstallGoal.setName("My App Install Goal");
            ConversionGoalRevenue addAppInstallGoalRevenue = new ConversionGoalRevenue();
            addAppInstallGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            addAppInstallGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            addAppInstallGoalRevenue.setCurrencyCode(null);
            addAppInstallGoal.setRevenue(addAppInstallGoalRevenue);
            // Account scope is not supported for app install goals. You can
            // set scope to Customer or don't set it for the same result.
            addAppInstallGoal.setScope(EntityScope.CUSTOMER);
            addAppInstallGoal.setStatus(ConversionGoalStatus.ACTIVE);
            // The TagId is inherited from the ConversionGoal base class,
            // however, App Install goals do not use a UET tag.
            addAppInstallGoal.setTagId(null);
            addConversionGoals.getConversionGoals().add(addAppInstallGoal);
            
            
            
            outputStatusMessage("-----\nAddConversionGoals:");
            AddConversionGoalsResponse addConversionGoalsResponse = CampaignManagementExampleHelper.addConversionGoals(
                    addConversionGoals);
            ArrayOfNullableOflong goalIds = addConversionGoalsResponse.getConversionGoalIds();
            ArrayOfBatchError conversionGoalErrors = addConversionGoalsResponse.getPartialErrors();
            outputStatusMessage("ConversionGoalIds:");
            CampaignManagementExampleHelper.outputArrayOfNullableOflong(goalIds);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(conversionGoalErrors);

            // Find the conversion goals that were added successfully. 

            ArrayOflong conversionGoalIds = new ArrayOflong();
            for (java.lang.Long goalId : goalIds.getLongs())
            {
                if (goalId != null)
                {
                    conversionGoalIds.getLongs().add((long)goalId);
                }
            }

            outputStatusMessage("List of errors returned from AddConversionGoals (if any):");
            CampaignManagementExampleHelper.outputArrayOfBatchError(addConversionGoalsResponse.getPartialErrors());

            ArrayList<ConversionGoalType> conversionGoalTypes = new ArrayList<ConversionGoalType>();
            conversionGoalTypes.add(ConversionGoalType.APP_INSTALL);
            conversionGoalTypes.add(ConversionGoalType.DURATION);
            conversionGoalTypes.add(ConversionGoalType.EVENT);
            conversionGoalTypes.add(ConversionGoalType.PAGES_VIEWED_PER_VISIT);
            conversionGoalTypes.add(ConversionGoalType.URL);
            
            ArrayList<ConversionGoalAdditionalField> returnAdditionalFields = new ArrayList<ConversionGoalAdditionalField>();
            returnAdditionalFields.add(ConversionGoalAdditionalField.VIEW_THROUGH_CONVERSION_WINDOW_IN_MINUTES);
            
            outputStatusMessage("-----\nGetConversionGoalsByIds:");
            GetConversionGoalsByIdsResponse getConversionGoalsByIdsResponse = CampaignManagementExampleHelper.getConversionGoalsByIds(
                    conversionGoalIds, 
                    conversionGoalTypes,
                    returnAdditionalFields);
            ArrayOfConversionGoal getConversionGoals = getConversionGoalsByIdsResponse.getConversionGoals();
            conversionGoalErrors = getConversionGoalsByIdsResponse.getPartialErrors();
            outputStatusMessage("ConversionGoals:");
            CampaignManagementExampleHelper.outputArrayOfConversionGoal(getConversionGoals);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(conversionGoalErrors);

            // Update the conversion goals

            ArrayOfConversionGoal updateConversionGoals = new ArrayOfConversionGoal();
            DurationGoal updateDurationGoal = new DurationGoal();
            updateDurationGoal.setConversionWindowInMinutes(60);
            updateDurationGoal.setCountType(ConversionGoalCountType.UNIQUE);
            // You can change the conversion goal type e.g. in this example an event goal
            // had been created above at index 1. Now we are using the returned identifier
            // at index 1 to update the type from EventGoal to DurationGoal.
            updateDurationGoal.setId(conversionGoalIds.getLongs().get(1));
            updateDurationGoal.setMinimumDurationInSeconds(120);
            updateDurationGoal.setName("My Updated Duration Goal");
            ConversionGoalRevenue updateDurationGoalRevenue = new ConversionGoalRevenue();
            updateDurationGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            updateDurationGoalRevenue.setValue(new java.math.BigDecimal(10.00));
            updateDurationGoalRevenue.setCurrencyCode(null);
            updateDurationGoal.setRevenue(updateDurationGoalRevenue);
            // The Scope cannot be updated, even if you update the goal type.
            // You can either send the same value or leave Scope empty.
            updateDurationGoal.setScope(EntityScope.ACCOUNT);
            updateDurationGoal.setStatus(ConversionGoalStatus.PAUSED);
            // You can update the tag as needed. In this example we will explicitly use the same UET tag.
            // To keep the UET tag unchanged, you can also leave this element nil or empty.
            updateDurationGoal.setTagId(tagId);
            updateConversionGoals.getConversionGoals().add(updateDurationGoal);
            
            EventGoal updateEventGoal = new EventGoal();
            // For both add and update conversion goal operations, you must include one or more  
            // of the following events: 
            // ActionExpression, CategoryExpression, LabelExpression, or Value.

            // For example if you do not include ActionExpression during update, 
            // any existing ActionOperator and ActionExpression settings will be deleted.
            updateEventGoal.setActionExpression(null);
            updateEventGoal.setActionOperator(null);
            updateEventGoal.setCategoryExpression("video");
            updateEventGoal.setCategoryOperator(ExpressionOperator.EQUALS);
            updateEventGoal.setId(conversionGoalIds.getLongs().get(0));
            updateEventGoal.setConversionWindowInMinutes(30);
            updateEventGoal.setCountType(ConversionGoalCountType.ALL);
            // You cannot update the operator unless you also include the expression.
            // The following attempt to update LabelOperator will result in an error.
            updateEventGoal.setLabelExpression(null);
            updateEventGoal.setLabelOperator(ExpressionOperator.EQUALS);
            updateEventGoal.setName("My Updated Event Goal");
            ConversionGoalRevenue updateEventGoalRevenue = new ConversionGoalRevenue();
            updateEventGoalRevenue.setType(ConversionGoalRevenueType.FIXED_VALUE);
            updateEventGoalRevenue.setValue(new java.math.BigDecimal(5.00));
            updateEventGoalRevenue.setCurrencyCode(null);
            updateEventGoal.setRevenue(updateEventGoalRevenue);
            // You must specify the previous settings unless you want
            // them replaced during the update conversion goal operation.
            updateEventGoal.setValue(new java.math.BigDecimal(5.00));
            updateEventGoal.setValueOperator(ValueOperator.EQUALS);
            updateConversionGoals.getConversionGoals().add(updateEventGoal);
            
            PagesViewedPerVisitGoal updatePagesViewedPerVisitGoal = new PagesViewedPerVisitGoal();
            updatePagesViewedPerVisitGoal.setId(conversionGoalIds.getLongs().get(2));
            updatePagesViewedPerVisitGoal.setName("My Updated Pages Viewed Per Visit Goal");
            // When updating a conversion goal, if the Revenue element is nil or empty then none 
            // of the nested properties will be updated. However, if this element is not nil or empty 
            // then you are effectively replacing any existing revenue properties. For example to delete 
            // any previous revenue settings, set the Revenue element to an empty ConversionGoalRevenue object.
            ConversionGoalRevenue updatePagesViewedPerVisitGoalRevenue = new ConversionGoalRevenue();
            updatePagesViewedPerVisitGoal.setRevenue(updatePagesViewedPerVisitGoalRevenue);
            updateConversionGoals.getConversionGoals().add(updatePagesViewedPerVisitGoal);
            
            UrlGoal updateUrlGoal = new UrlGoal();
            updateUrlGoal.setId(conversionGoalIds.getLongs().get(3));
            updateUrlGoal.setName("My Updated Url Goal");
            // If not specified during update, the previous Url settings are retained.
            // If the expression is set, then the operator must also be set, and vice versa.
            updateUrlGoal.setUrlExpression("contoso");
            updateUrlGoal.setUrlOperator(ExpressionOperator.BEGINS_WITH);
            updateConversionGoals.getConversionGoals().add(updateUrlGoal);
            
            outputStatusMessage("-----\nUpdateConversionGoals:");
            UpdateConversionGoalsResponse updateConversionGoalsResponse = CampaignManagementExampleHelper.updateConversionGoals(
                    updateConversionGoals);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(updateConversionGoalsResponse.getPartialErrors());
            
            outputStatusMessage("-----\nGetConversionGoalsByIds:");
            getConversionGoalsByIdsResponse = CampaignManagementExampleHelper.getConversionGoalsByIds(
                    conversionGoalIds, 
                    conversionGoalTypes,
                    returnAdditionalFields);
            getConversionGoals = getConversionGoalsByIdsResponse.getConversionGoals();
            conversionGoalErrors = getConversionGoalsByIdsResponse.getPartialErrors();
            outputStatusMessage("ConversionGoals:");
            CampaignManagementExampleHelper.outputArrayOfConversionGoal(getConversionGoals);
            outputStatusMessage("PartialErrors:");
            CampaignManagementExampleHelper.outputArrayOfBatchError(conversionGoalErrors);
        } 
        catch (Exception ex) {
            String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
            outputStatusMessage(faultXml);
            String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
            outputStatusMessage(message);
        }
    }     
}
<?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;

// Specify the Microsoft\BingAds\V13\CampaignManagement classes that will be used.
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoal;
use Microsoft\BingAds\V13\CampaignManagement\AppInstallGoal;
use Microsoft\BingAds\V13\CampaignManagement\DurationGoal;
use Microsoft\BingAds\V13\CampaignManagement\EventGoal;
use Microsoft\BingAds\V13\CampaignManagement\PagesViewedPerVisitGoal;
use Microsoft\BingAds\V13\CampaignManagement\UrlGoal;
use Microsoft\BingAds\V13\CampaignManagement\ExpressionOperator;
use Microsoft\BingAds\V13\CampaignManagement\ValueOperator;
use Microsoft\BingAds\V13\CampaignManagement\UetTag;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalAdditionalField;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalRevenue;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalType;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalRevenueType;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalCountType;
use Microsoft\BingAds\V13\CampaignManagement\ConversionGoalStatus;
use Microsoft\BingAds\V13\CampaignManagement\EntityScope;

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

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

    // Before you can track conversions or target audiences using a remarketing list 
    // you need to create a UET tag, and then add the UET tag tracking code to every page of your website.
    // For more information, please see Universal Event Tracking at https://go.microsoft.com/fwlink/?linkid=829965.

    // First you should call the GetUetTagsByIds operation to check whether a tag has already been created. 
    // You can leave the TagIds element null or empty to request all UET tags available for the customer.

    print("-----\r\nGetUetTagsByIds:\r\n");
    $getUetTagsByIdsResponse = CampaignManagementExampleHelper::GetUetTagsByIds(
        null
    );
    $uetTags = $getUetTagsByIdsResponse->UetTags;
    print("UetTags:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfUetTag($uetTags);
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($getUetTagsByIdsResponse->PartialErrors);
    
    // If you do not already have a UET tag that can be used, or if you need another UET tag, 
    // call the AddUetTags service operation to create a new UET tag. If the call is successful, 
    // the tracking script that you should add to your website is included in a corresponding 
    // UetTag within the response message. 

    if(count((array)$uetTags) == 0 || !isset($uetTags->UetTag))
    //if ($uetTags == null || count($uetTags->UetTag) < 1)
    {
        $addUetTags = array();
        $uetTag = new UetTag();
        $uetTag->Description = "My First Uet Tag";
        $uetTag->Name = "New Uet Tag";
        $addUetTags[] = $uetTag;
                
        print("-----\r\nAddUetTags:\r\n");
        $addUetTagsResponse = CampaignManagementExampleHelper::AddUetTags(
            $addUetTags
        );
        $uetTags = $addUetTagsResponse->UetTags;
        print("UetTags:\r\n");
        CampaignManagementExampleHelper::OutputArrayOfUetTag($uetTags);
        print("PartialErrors:\r\n");
        CampaignManagementExampleHelper::OutputArrayOfBatchError($addUetTagsResponse->PartialErrors);
    }

    if ($uetTags == null || count($uetTags->UetTag) < 1)
    {
        printf(
            "You do not have any UET tags registered for CustomerId %s.\r\n", 
            $CustomerId
        );
        return;
    }

    // After you retreive the tracking script from the AddUetTags or GetUetTagsByIds operation, 
    // the next step is to add the UET tag tracking code to your website.
    // We will use the same UET tag for the remainder of this example.

    $tagId = $uetTags->UetTag[0]->Id;                              
    
    // Add conversion goals that depend on the UET Tag Id retreived above.
    // Please note that you cannot delete conversion goals. If you want to stop 
    // tracking conversions for the goal, you can set the goal status to Paused.

    $addConversionGoals = array();
    
    $addDurationGoal = new DurationGoal();
    $addDurationGoal->ConversionWindowInMinutes = 30;
    $addDurationGoal->CountType = ConversionGoalCountType::All;
    $addDurationGoal->MinimumDurationInSeconds = 60;
    $addDurationGoal->Name = "My Duration Goal";
    $addDurationGoalRevenue = new ConversionGoalRevenue();
    $addDurationGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $addDurationGoalRevenue->Value = 5.00;
    $addDurationGoalRevenue->CurrencyCode = null;
    $addDurationGoal->Revenue = $addDurationGoalRevenue;
    $addDurationGoal->Scope = EntityScope::Account;
    $addDurationGoal->Status = ConversionGoalStatus::Active;
    $addDurationGoal->TagId = $tagId;
    $encodedDurationGoal = new SoapVar(
        $addDurationGoal, 
        SOAP_ENC_OBJECT, 
        'DurationGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $addConversionGoals[] = $encodedDurationGoal;    
    
    $addEventGoal = new EventGoal();
    $addEventGoal->GoalCategory = ConversionGoalCategory::Purchase;
    // The type of user interaction you want to track.
    $addEventGoal->ActionExpression = "play";
    $addEventGoal->ActionOperator = ExpressionOperator::Contains;
    // The category of event you want to track. 
    $addEventGoal->CategoryExpression = "video";
    $addEventGoal->CategoryOperator = ExpressionOperator::Contains;
    $addEventGoal->ConversionWindowInMinutes = 30;
    $addEventGoal->CountType = ConversionGoalCountType::All;
    // The name of the element that caused the action.
    $addEventGoal->LabelExpression = "trailer";
    $addEventGoal->LabelOperator = ExpressionOperator::Contains;
    $addEventGoal->Name = "My Event Goal";
    $addEventGoalRevenue = new ConversionGoalRevenue();
    $addEventGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $addEventGoalRevenue->Value = 5.00;
    $addEventGoalRevenue->CurrencyCode = null;
    $addEventGoal->Revenue = $addEventGoalRevenue;
    $addEventGoal->Scope = EntityScope::Account;
    $addEventGoal->Status = ConversionGoalStatus::Active;
    $addEventGoal->TagId = $tagId;
    // A numerical value associated with that event. 
    // Could be length of the video played etc.
    $addEventGoal->Value = 5.00;
    $addEventGoal->ValueOperator = ValueOperator::Equals;
    $encodedEventGoal = new SoapVar(
        $addEventGoal, 
        SOAP_ENC_OBJECT, 
        'EventGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $addConversionGoals[] = $encodedEventGoal;
        
    $addPagesViewedPerVisitGoal = new PagesViewedPerVisitGoal();
    $addPagesViewedPerVisitGoal->ConversionWindowInMinutes = 30;
    $addPagesViewedPerVisitGoal->CountType = ConversionGoalCountType::All;
    $addPagesViewedPerVisitGoal->MinimumPagesViewed = 5;
    $addPagesViewedPerVisitGoal->Name = "My Pages Viewed Per Visit Goal";
    $addPagesViewedPerVisitGoalRevenue = new ConversionGoalRevenue();
    $addPagesViewedPerVisitGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $addPagesViewedPerVisitGoalRevenue->Value = 5.00;
    $addPagesViewedPerVisitGoalRevenue->CurrencyCode = null;
    $addPagesViewedPerVisitGoal->Revenue = $addPagesViewedPerVisitGoalRevenue;
    $addPagesViewedPerVisitGoal->Scope = EntityScope::Account;
    $addPagesViewedPerVisitGoal->Status = ConversionGoalStatus::Active;
    $addPagesViewedPerVisitGoal->TagId = $tagId;
    $encodedPagesViewedPerVisitGoal = new SoapVar(
        $addPagesViewedPerVisitGoal, 
        SOAP_ENC_OBJECT, 
        'PagesViewedPerVisitGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $addConversionGoals[] = $encodedPagesViewedPerVisitGoal;
    
    $addUrlGoal = new UrlGoal();
    $addUrlGoal->GoalCategory = ConversionGoalCategory::Purchase;
    $addUrlGoal->ConversionWindowInMinutes = 30;
    $addUrlGoal->CountType = ConversionGoalCountType::All;
    $addUrlGoal->Name = "My Url Goal";
    $addUrlGoalRevenue = new ConversionGoalRevenue();
    $addUrlGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $addUrlGoalRevenue->Value = 5.00;
    $addUrlGoalRevenue->CurrencyCode = null;
    $addUrlGoal->Revenue = $addUrlGoalRevenue;
    $addUrlGoal->Scope = EntityScope::Account;
    $addUrlGoal->Status = ConversionGoalStatus::Active;
    $addUrlGoal->UrlExpression = "contoso";
    $addUrlGoal->UrlOperator = ExpressionOperator::Contains;
    $addUrlGoal->TagId = $tagId;
    $encodedUrlGoal = new SoapVar(
        $addUrlGoal, 
        SOAP_ENC_OBJECT, 
        'UrlGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $addConversionGoals[] = $encodedUrlGoal;
    
    $addAppInstallGoal = new AppInstallGoal();
    // You must provide a valid app platform and app store identifier, 
    // otherwise this goal will not be added successfully. 
    $addAppInstallGoal->AppPlatform = "Windows";
    $addAppInstallGoal->AppStoreId = "AppStoreIdGoesHere";
    $addAppInstallGoal->ConversionWindowInMinutes = 30;
    $addAppInstallGoal->CountType = ConversionGoalCountType::All;
    $addAppInstallGoal->Name = "My App Install Goal";
    $addAppInstallGoalRevenue = new ConversionGoalRevenue();
    $addAppInstallGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $addAppInstallGoalRevenue->Value = 5.00;
    $addAppInstallGoalRevenue->CurrencyCode = null;
    $addAppInstallGoal->Revenue = $addAppInstallGoalRevenue;
    // Account scope is not supported for app install goals. You can
    // set scope to Customer or don't set it for the same result.
    $addAppInstallGoal->Scope = EntityScope::Customer;
    $addAppInstallGoal->Status = ConversionGoalStatus::Active;
    // The TagId is inherited from the ConversionGoal base class,
    // however, App Install goals do not use a UET tag.
    $addAppInstallGoal->TagId = null;
    $encodedAppInstallGoal = new SoapVar(
        $addAppInstallGoal, 
        SOAP_ENC_OBJECT, 
        'AppInstallGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $addConversionGoals[] = $encodedAppInstallGoal;
    
    print("-----\r\nAddConversionGoals:\r\n");
    $addConversionGoalsResponse = CampaignManagementExampleHelper::AddConversionGoals(
        $addConversionGoals
    );
    print("ConversionGoalIds:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfLong($addConversionGoalsResponse->ConversionGoalIds);
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($addConversionGoalsResponse->PartialErrors);

    // Find the conversion goals that were added successfully. 

    $conversionGoalIds = array();
    foreach ($addConversionGoalsResponse->ConversionGoalIds->long as $goalId)
    {
        if (!empty($goalId))
        {
            $conversionGoalIds[] = $goalId;
        }
    }

    $conversionGoalTypes = array(
        ConversionGoalType::AppInstall,
        ConversionGoalType::Duration,
        ConversionGoalType::Event,
        ConversionGoalType::PagesViewedPerVisit,
        ConversionGoalType::Url
    );
    
    $returnAdditionalFields = array(
        ConversionGoalAdditionalField::ViewThroughConversionWindowInMinutes,
        ConversionGoalAdditionalField::IsExternallyAttributed,
        ConversionGoalAdditionalField::GoalCategory
    );

    print("-----\r\nGetConversionGoalsByIds:\r\n");
    $getConversionGoalsByIdsResponse = CampaignManagementExampleHelper::GetConversionGoalsByIds(
        $conversionGoalIds, 
        $conversionGoalTypes,
        $returnAdditionalFields
    );
    $getConversionGoals = $getConversionGoalsByIdsResponse->ConversionGoals;
    print("ConversionGoals:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfConversionGoal($getConversionGoals);
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($getConversionGoalsByIdsResponse->PartialErrors);    

    // Update the conversion goals
    
    $updateConversionGoals = array();
    
    $updateDurationGoal = new DurationGoal();
    $updateDurationGoal->ConversionWindowInMinutes = 60;
    $updateDurationGoal->CountType = ConversionGoalCountType::Unique;
    // You can change the conversion goal type e.g. in this example an event goal
    // had been created above at index 1. Now we are using the returned identifier
    // at index 1 to update the type from EventGoal to DurationGoal.
    $updateDurationGoal->Id = $conversionGoalIds[1];
    $updateDurationGoal->MinimumDurationInSeconds = 120;
    $updateDurationGoal->Name = "My Updated Duration Goal";
    $updateDurationGoalRevenue = new ConversionGoalRevenue();
    $updateDurationGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $updateDurationGoalRevenue->Value = 10.00;
    $updateDurationGoalRevenue->CurrencyCode = null;
    $updateDurationGoal->Revenue = $updateDurationGoalRevenue;
    // The Scope cannot be updated, even if you update the goal type.
    // You can either send the same value or leave Scope empty.
    $updateDurationGoal->Scope = EntityScope::Account;
    $updateDurationGoal->Status = ConversionGoalStatus::Paused;
    // You can update the tag as needed. In this example we will explicitly use the same UET tag.
    // To keep the UET tag unchanged, you can also leave this element nil or empty.
    $updateDurationGoal->TagId = $tagId;
    $encodedDurationGoal = new SoapVar(
        $updateDurationGoal, 
        SOAP_ENC_OBJECT, 
        'DurationGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $updateConversionGoals[] = $encodedDurationGoal;
    
    $updateEventGoal = new EventGoal();
    // For both add and update conversion goal operations, you must include one or more  
    // of the following event operator pairs: 
    // (ActionOperator and ActionExpression), (CategoryOperator and CategoryExpression), 
    // (LabelOperator and LabelExpression), (ValueOperator and Value).
    // Each event pair (e.g. ActionOperator and ActionExpression) is optional if you include 
    // one or more of the other events.

    // For example if you do not include ActionOperator and ActionExpression during update, 
    // any existing ActionOperator and ActionExpression settings will be deleted.
    $updateEventGoal->ActionExpression = null;
    $updateEventGoal->ActionOperator = null;
    $updateEventGoal->CategoryExpression = "video";
    $updateEventGoal->CategoryOperator = ExpressionOperator::Equals;
    $updateEventGoal->Id = $conversionGoalIds[0];
    $updateEventGoal->ConversionWindowInMinutes = 30;
    $updateEventGoal->CountType = ConversionGoalCountType::All;
    // You cannot update the expression unless you also include the expression.
    // Likewise, you cannot update the operator unless you also include the expression.
    // The following attempt to update LabelOperator will result in an error.
    $updateEventGoal->LabelExpression = null;
    $updateEventGoal->LabelOperator = ExpressionOperator::Equals;
    $updateEventGoal->Name = "My Updated Event Goal";
    $updateEventGoalRevenue = new ConversionGoalRevenue();
    $updateEventGoalRevenue->Type = ConversionGoalRevenueType::FixedValue;
    $updateEventGoalRevenue->Value = 5.00;
    $updateEventGoalRevenue->CurrencyCode = null;
    $updateEventGoal->Revenue = $updateEventGoalRevenue;
    // You must specify the previous settings for Value and ValueOperator,
    // unless you want them deleted during the update conversion goal operation.
    $updateEventGoal->Value = 5.00;
    $updateEventGoal->ValueOperator = ValueOperator::Equals;
    $encodedEventGoal = new SoapVar(
        $updateEventGoal, 
        SOAP_ENC_OBJECT, 
        'EventGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $updateConversionGoals[] = $encodedEventGoal;
    
    $updatePagesViewedPerVisitGoal = new PagesViewedPerVisitGoal();
    $updatePagesViewedPerVisitGoal->Id = $conversionGoalIds[2];
    $updatePagesViewedPerVisitGoal->Name = "My Updated Pages Viewed Per Visit Goal";
    // When updating a conversion goal, if the Revenue element is nil or empty then none 
    // of the nested properties will be updated. However, if this element is not nil or empty 
    // then you are effectively replacing any existing revenue properties. For example to delete 
    // any previous revenue settings, set the Revenue element to an empty ConversionGoalRevenue object.
    $updatePagesViewedPerVisitGoalRevenue = new ConversionGoalRevenue();
    $updatePagesViewedPerVisitGoal->Revenue = $updatePagesViewedPerVisitGoalRevenue;
    $encodedPagesViewedPerVisitGoal = new SoapVar(
        $updatePagesViewedPerVisitGoal, 
        SOAP_ENC_OBJECT, 
        'PagesViewedPerVisitGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $updateConversionGoals[] = $encodedPagesViewedPerVisitGoal;
    
    $updateUrlGoal = new UrlGoal();
    $updateUrlGoal->Id = $conversionGoalIds[3];
    $updateUrlGoal->Name = "My Updated Url Goal";
    // If not specified during update, the previous Url settings are retained.
    // If the expression is set, then the operator must also be set, and vice versa.
    $updateUrlGoal->UrlExpression = "contoso";
    $updateUrlGoal->UrlOperator = ExpressionOperator::BeginsWith;
    $encodedUrlGoal = new SoapVar(
        $updateUrlGoal, 
        SOAP_ENC_OBJECT, 
        'UrlGoal', 
        $GLOBALS['CampaignManagementProxy']->GetNamespace()
    );
    $updateConversionGoals[] = $encodedUrlGoal;
    
    print("-----\r\nUpdateConversionGoals:\r\n");
    $updateConversionGoalsResponse = CampaignManagementExampleHelper::UpdateConversionGoals(
        $updateConversionGoals
    );
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($updateConversionGoalsResponse->PartialErrors);

    print("-----\r\nGetConversionGoalsByIds:\r\n");
    $getConversionGoalsByIdsResponse = CampaignManagementExampleHelper::GetConversionGoalsByIds(
        $conversionGoalIds, 
        $conversionGoalTypes,
        null
    );
    $getConversionGoals = $getConversionGoalsByIdsResponse->ConversionGoals;
    print("ConversionGoals:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfConversionGoal($getConversionGoals);
    print("PartialErrors:\r\n");
    CampaignManagementExampleHelper::OutputArrayOfBatchError($getConversionGoalsByIdsResponse->PartialErrors);    
}
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";
    }
}
from auth_helper import *
from campaignmanagement_example_helper import *

# You must provide credentials in auth_helper.py.

def main(authorization_data):

    try:
        # Before you can track conversions or target audiences using a remarketing list 
        # you need to create a UET tag, and then add the UET tag tracking code to every page of your website.
        # For more information, please see Universal Event Tracking at https://go.microsoft.com/fwlink/?linkid=829965.

        # First you should call the GetUetTagsByIds operation to check whether a tag has already been created. 
        # You can leave the TagIds element null or empty to request all UET tags available for the customer.

        output_status_message("-----\nGetUetTagsByIds:")
        get_uet_tags_by_ids_response=campaign_service.GetUetTagsByIds(
            TagIds=None)
        uet_tags=get_uet_tags_by_ids_response.UetTags
        output_status_message("UetTags:")
        output_array_of_uettag(uet_tags)
        output_status_message("PartialErrors:")
        output_array_of_batcherror(get_uet_tags_by_ids_response.PartialErrors)

        # If you do not already have a UET tag that can be used, or if you need another UET tag, 
        # call the AddUetTags service operation to create a new UET tag. If the call is successful, 
        # the tracking script that you should add to your website is included in a corresponding 
        # UetTag within the response message. 

        if uet_tags is None or len(uet_tags) < 1:
            uet_tags=campaign_service.factory.create('ArrayOfUetTag')
            uet_tag=set_elements_to_none(campaign_service.factory.create('UetTag'))
            uet_tag.Description="My First Uet Tag"
            uet_tag.Name="New Uet Tag"
            uet_tags.UetTag.append(uet_tag)
            
            add_uet_tags_response=campaign_service.AddUetTags(
                UetTags=uet_tags)
            uet_tags=add_uet_tags_response.UetTags
            output_status_message("UetTags:")
            output_array_of_uettag(uet_tags)
            output_status_message("PartialErrors:")
            output_array_of_batcherror(add_uet_tags_response.PartialErrors)

        if uet_tags is None or len(uet_tags) < 1:
            output_status_message(
                "You do not have any UET tags registered for CustomerId {0}.".format(authorization_data.customer_id)
            )
            sys.exit(0)
        
        # After you retreive the tracking script from the AddUetTags or GetUetTagsByIds operation, 
        # the next step is to add the UET tag tracking code to your website. 
        # We will use the same UET tag for the remainder of this example.

        tag_id = uet_tags['UetTag'][0].Id

        # Add conversion goals that depend on the UET Tag Id retreived above.
        # Please note that you cannot delete conversion goals. If you want to stop 
        # tracking conversions for the goal, you can set the goal status to Paused.

        conversion_goals=campaign_service.factory.create('ArrayOfConversionGoal')

        duration_goal=set_elements_to_none(campaign_service.factory.create('DurationGoal'))
        duration_goal.ConversionWindowInMinutes = 30
        duration_goal.CountType = 'All'
        duration_goal.MinimumDurationInSeconds = 60
        duration_goal.Name = "My Duration Goal"
        duration_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        duration_goal_revenue.Type='FixedValue'
        duration_goal_revenue.Value=5.00
        duration_goal_revenue.CurrencyCode=None
        duration_goal.Revenue = duration_goal_revenue
        duration_goal.Scope = 'Account'
        duration_goal.Status = 'Active'
        duration_goal.TagId = tag_id
        conversion_goals.ConversionGoal.append(duration_goal)

        event_goal=set_elements_to_none(campaign_service.factory.create('EventGoal'))
        event_goal.GoalCategory = "Purchase"
        # The type of user interaction you want to track.
        event_goal.ActionExpression = "play"
        event_goal.ActionOperator = 'Contains'
        # The category of event you want to track. 
        event_goal.CategoryExpression = "video"
        event_goal.CategoryOperator = 'Contains'
        event_goal.ConversionWindowInMinutes = 30
        event_goal.CountType = 'All'
        # The name of the element that caused the action.
        event_goal.LabelExpression = "trailer"
        event_goal.LabelOperator = 'Contains'
        event_goal.Name = "My Event Goal"
        event_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        event_goal_revenue.Type='FixedValue'
        event_goal_revenue.Value=5.00
        event_goal_revenue.CurrencyCode=None
        event_goal.Revenue = event_goal_revenue
        event_goal.Scope = 'Account'
        event_goal.Status = 'Active'
        event_goal.TagId = tag_id
        # A numerical value associated with that event. 
        # Could be length of the video played etc.
        event_goal.Value = 5.00
        event_goal.ValueOperator = 'Equals'
        conversion_goals.ConversionGoal.append(event_goal)

        pages_viewed_per_visit_goal=set_elements_to_none(campaign_service.factory.create('PagesViewedPerVisitGoal'))
        pages_viewed_per_visit_goal.ConversionWindowInMinutes = 30
        pages_viewed_per_visit_goal.CountType = 'All'
        pages_viewed_per_visit_goal.MinimumPagesViewed = 5
        pages_viewed_per_visit_goal.Name = "My Pages Viewed Per Visit Goal"
        pages_viewed_per_visit_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        pages_viewed_per_visit_goal_revenue.Type='FixedValue'
        pages_viewed_per_visit_goal_revenue.Value=5.00
        pages_viewed_per_visit_goal_revenue.CurrencyCode=None
        pages_viewed_per_visit_goal.Revenue = pages_viewed_per_visit_goal_revenue
        pages_viewed_per_visit_goal.Scope = 'Account'
        pages_viewed_per_visit_goal.Status = 'Active'
        pages_viewed_per_visit_goal.TagId = tag_id
        conversion_goals.ConversionGoal.append(pages_viewed_per_visit_goal)
            
        url_goal=set_elements_to_none(campaign_service.factory.create('UrlGoal'))
        url_goal.GoalCategory = "Purchase"
        url_goal.ConversionWindowInMinutes = 30
        url_goal.CountType = 'All'
        url_goal.Name = "My Url Goal"
        url_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        url_goal_revenue.Type='FixedValue'
        url_goal_revenue.Value=5.00
        url_goal_revenue.CurrencyCode=None
        url_goal.Revenue = url_goal_revenue
        url_goal.Scope = 'Account'
        url_goal.Status = 'Active'
        url_goal.TagId = tag_id
        url_goal.UrlExpression = "contoso"
        url_goal.UrlOperator = 'Contains'
        conversion_goals.ConversionGoal.append(url_goal)

        app_install_goal=set_elements_to_none(campaign_service.factory.create('AppInstallGoal'))
        # You must provide a valid app platform and app store identifier, 
        # otherwise this goal will not be added successfully. 
        app_install_goal.AppPlatform = "Windows"
        app_install_goal.AppStoreId = "AppStoreIdGoesHere"
        app_install_goal.ConversionWindowInMinutes = 30
        app_install_goal.CountType = 'All'
        app_install_goal.Name = "My App Install Goal"
        app_install_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        app_install_goal_revenue.Type='FixedValue'
        app_install_goal_revenue.Value=5.00
        app_install_goal_revenue.CurrencyCode=None
        app_install_goal.Revenue = app_install_goal_revenue
        # Account scope is not supported for app install goals. You can
        # set scope to Customer or don't set it for the same result.
        app_install_goal.Scope = 'Customer'
        app_install_goal.Status = 'Active'
        # The TagId is inherited from the ConversionGoal base class,
        # however, App Install goals do not use a UET tag.
        app_install_goal.TagId = None
        conversion_goals.ConversionGoal.append(app_install_goal)

        output_status_message("-----\nAddConversionGoals:")
        add_conversion_goals_response=campaign_service.AddConversionGoals(
            ConversionGoals=conversion_goals)
        goal_ids={
            'long': add_conversion_goals_response.ConversionGoalIds['long'] if add_conversion_goals_response.ConversionGoalIds['long'] else None
        }
        output_status_message("ConversionGoalIds:")
        output_array_of_long(goal_ids)
        output_status_message("PartialErrors:")
        output_array_of_batcherror(add_conversion_goals_response.PartialErrors)
        
        # Find the conversion goals that were added successfully. 
        
        conversion_goal_ids = []
        for goal_id in goal_ids['long']:
            if goal_id is not None:
                conversion_goal_ids.append(goal_id)
        
        conversion_goal_types='AppInstall ' \
                              'Duration ' \
                              'Event ' \
                              'PagesViewedPerVisit ' \
                              'Url'
        
        return_additional_fields = 'ViewThroughConversionWindowInMinutes'

        output_status_message("-----\nGetConversionGoalsByIds:")
        get_conversion_goals_response = campaign_service.GetConversionGoalsByIds(
            ConversionGoalIds={'long': conversion_goal_ids}, 
            ConversionGoalTypes=conversion_goal_types,
            ReturnAdditionalFields=return_additional_fields
        )
        output_status_message("ConversionGoals:")
        output_array_of_conversiongoal(get_conversion_goals_response.ConversionGoals)
        output_status_message("PartialErrors:")
        output_array_of_batcherror(get_conversion_goals_response.PartialErrors)
        
        update_conversion_goals=campaign_service.factory.create('ArrayOfConversionGoal')

        update_duration_goal=set_elements_to_none(campaign_service.factory.create('DurationGoal'))
        update_duration_goal.ConversionWindowInMinutes = 60
        update_duration_goal.CountType = 'Unique'
        # You can change the conversion goal type e.g. in this example an event goal
        # had been created above at index 1. Now we are using the returned identifier
        # at index 1 to update the type from EventGoal to DurationGoal.
        update_duration_goal.Id=conversion_goal_ids[1]
        update_duration_goal.MinimumDurationInSeconds = 120
        update_duration_goal.Name = "My Updated Duration Goal"
        update_duration_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        update_duration_goal_revenue.Type='FixedValue'
        update_duration_goal_revenue.Value=10.00
        update_duration_goal_revenue.CurrencyCode=None
        update_duration_goal.Revenue = update_duration_goal_revenue
        # The Scope cannot be updated, even if you update the goal type.
        # You can either send the same value or leave Scope empty.
        update_duration_goal.Scope = 'Account'
        update_duration_goal.Status = 'Paused'
        # You can update the tag as needed. In this example we will explicitly use the same UET tag.
        # To keep the UET tag unchanged, you can also leave this element nil or empty.
        update_duration_goal.TagId = tag_id
        update_conversion_goals.ConversionGoal.append(update_duration_goal)

        update_event_goal=set_elements_to_none(campaign_service.factory.create('EventGoal'))
        # For both add and update conversion goal operations, you must include one or more  
        # of the following events:
        # ActionExpression, CategoryExpression, LabelExpression, or Value. 
        
        # For example if you do not include ActionExpression during update,
        # any existing ActionOperator and ActionExpression settings will be deleted.
        update_event_goal.ActionExpression = None
        update_event_goal.ActionOperator = None
        update_event_goal.CategoryExpression = "video"
        update_event_goal.CategoryOperator = 'Equals'
        update_event_goal.Id = conversion_goal_ids[0]
        # You cannot update the operator unless you also include the expression.
        # The following attempt to update LabelOperator will result in an error.
        update_event_goal.LabelExpression = None
        update_event_goal.LabelOperator = 'Equals'
        update_event_goal.Name = "My Updated Event Goal"
        update_event_goal_revenue=set_elements_to_none(campaign_service.factory.create('ConversionGoalRevenue'))
        update_event_goal_revenue.Type='VariableValue'
        update_event_goal_revenue.Value=5.00
        update_event_goal_revenue.CurrencyCode=None
        update_event_goal.Revenue = update_event_goal_revenue
        # You must specify the previous settings unless you want
        # them replaced during the update conversion goal operation.
        update_event_goal.Value=5.00
        update_event_goal.ValueOperator = 'GreaterThan'
        update_conversion_goals.ConversionGoal.append(update_event_goal)

        update_pages_viewed_per_visit_goal=set_elements_to_none(campaign_service.factory.create('PagesViewedPerVisitGoal'))
        update_pages_viewed_per_visit_goal.Id = conversion_goal_ids[2]
        update_pages_viewed_per_visit_goal.Name = "My Updated Pages Viewed Per Visit Goal"
        update_conversion_goals.ConversionGoal.append(update_pages_viewed_per_visit_goal)
            
        update_url_goal=set_elements_to_none(campaign_service.factory.create('UrlGoal'))
        update_url_goal.Id = conversion_goal_ids[3]
        update_url_goal.Name = "My Updated Url Goal"
        # If not specified during update, the previous Url settings are retained.
        # If the expression is set, then the operator must also be set, and vice versa.
        update_url_goal.UrlExpression = 'Contoso'
        update_url_goal.UrlOperator = 'BeginsWith'
        update_conversion_goals.ConversionGoal.append(update_url_goal)

        output_status_message("-----\nUpdateConversionGoals:")
        update_conversion_goals_response = campaign_service.UpdateConversionGoals(
            ConversionGoals=update_conversion_goals)
        if hasattr(update_conversion_goals_response, 'BatchError'):
            output_status_message("PartialErrors:")
            output_array_of_batcherror(update_conversion_goals_response)
                
        output_status_message("-----\nGetConversionGoalsByIds:")
        get_conversion_goals_response = campaign_service.GetConversionGoalsByIds(
            ConversionGoalIds={'long': conversion_goal_ids}, 
            ConversionGoalTypes=conversion_goal_types,
            ReturnAdditionalFields=return_additional_fields)
        output_status_message("ConversionGoals:")
        output_array_of_conversiongoal(get_conversion_goals_response.ConversionGoals)
        output_status_message("PartialErrors:")
        output_array_of_batcherror(get_conversion_goals_response.PartialErrors)

    except WebFault as ex:
        output_webfault_errors(ex)
    except Exception as ex:
        output_status_message(ex)

# Main execution
if __name__ == '__main__':

    print("Loading the web service client proxies...")
    
    authorization_data=AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )

    campaign_service=ServiceClient(
        service='CampaignManagementService', 
        version=13,
        authorization_data=authorization_data, 
        environment=ENVIRONMENT,
    )
        
    authenticate(authorization_data)
        
    main(authorization_data)

See Also

Get Started with the Bing Ads API