Negative Keywords Code Example

This example demonstrates how to associate negative keywords and negative keyword lists with a campaign.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V11.CampaignManagement;
using Microsoft.BingAds;


namespace BingAdsExamplesLibrary.V11
{
    /// <summary>
    /// This example demonstrates how to associate negative keywords and negative keyword lists with a campaign.
    /// </summary>
    public class NegativeKeywords : ExampleBase
    {
        public override string Description
        {
            get { return "Negative Keywords | Campaign Management V11"; }
        }

        public async override Task RunAsync(AuthorizationData authorizationData)
        {
            try
            {
                CampaignService = new ServiceClient<ICampaignManagementService>(authorizationData);

                // Add a campaign that will later be associated with negative keywords. 

                var campaigns = new[]{
                    new Campaign
                    {
                        Name = "Women's Shoes " + DateTime.UtcNow,
                        Description = "Red shoes line.",

                        // You must choose to set either the shared  budget ID or daily amount.
                        // You can set one or the other, but you may not set both.
                        BudgetId = null,
                        DailyBudget = 50,
                        BudgetType = BudgetLimitType.DailyBudgetStandard,
                        BiddingScheme = new EnhancedCpcBiddingScheme(),

                        TimeZone = "PacificTimeUSCanadaTijuana",
                    }
                };

                AddCampaignsResponse addCampaignsResponse = await AddCampaignsAsync(authorizationData.AccountId, campaigns);
                long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray();
                BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
                OutputIds(campaignIds);
                OutputPartialErrors(campaignErrors);
                long campaignId = (long)campaignIds[0];

                // You may choose to associate an exclusive set of negative keywords to an individual campaign 
                // or ad group. An exclusive set of negative keywords cannot be shared with other campaigns 
                // or ad groups. This example only associates negative keywords with a campaign.

                var entityNegativeKeywords = new[]
                {
                    new EntityNegativeKeyword
                    {
                        EntityId = campaignId,
                        EntityType = "Campaign",
                        NegativeKeywords = new[]
                        {
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Phrase,
                                Text = "auto"
                            },
                            new NegativeKeyword
                            {
                                MatchType = MatchType.Phrase,
                                Text = "auto"
                            },
                        }
                    }
                };

                AddNegativeKeywordsToEntitiesResponse addNegativeKeywordsToEntitiesResponse =
                    await AddNegativeKeywordsToEntitiesAsync(entityNegativeKeywords);
                OutputNegativeKeywordIds(addNegativeKeywordsToEntitiesResponse.NegativeKeywordIds);
                OutputBatchErrorCollections(addNegativeKeywordsToEntitiesResponse.NestedPartialErrors);
                if (addNegativeKeywordsToEntitiesResponse.NestedPartialErrors == null
                    || addNegativeKeywordsToEntitiesResponse.NestedPartialErrors.Count == 0)
                {
                    OutputStatusMessage("Added an exclusive set of negative keywords to the Campaign.\n");
                    OutputNegativeKeywordIds(addNegativeKeywordsToEntitiesResponse.NegativeKeywordIds);
                }
                else
                {
                    OutputBatchErrorCollections(addNegativeKeywordsToEntitiesResponse.NestedPartialErrors);
                }

                GetNegativeKeywordsByEntityIdsResponse getNegativeKeywordsByEntityIdsResponse =
                    await GetNegativeKeywordsByEntityIdsAsync(new[] { campaignId }, "Campaign", authorizationData.AccountId);
                OutputEntityNegativeKeywords(getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords);
                OutputPartialErrors(getNegativeKeywordsByEntityIdsResponse.PartialErrors);
                if (getNegativeKeywordsByEntityIdsResponse.PartialErrors == null
                    || getNegativeKeywordsByEntityIdsResponse.PartialErrors.Count == 0)
                {
                    OutputStatusMessage("Retrieved an exclusive set of negative keywords for the Campaign.\n");
                    OutputEntityNegativeKeywords(getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords);
                }
                else
                {
                    OutputPartialErrors(getNegativeKeywordsByEntityIdsResponse.PartialErrors);
                }
                
                // If you attempt to delete a negative keyword without an identifier the operation will
                // succeed but will return partial errors corresponding to the index of the negative keyword
                // that was not deleted. 
                var nestedPartialErrors = (BatchErrorCollection[])(await DeleteNegativeKeywordsFromEntitiesAsync(entityNegativeKeywords)).NestedPartialErrors;
                if (nestedPartialErrors == null || nestedPartialErrors.Length == 0)
                {
                    OutputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
                }
                else
                {
                    OutputStatusMessage("Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.");
                    OutputBatchErrorCollections(nestedPartialErrors);
                }

                // Delete the negative keywords with identifiers that were returned above.
                nestedPartialErrors = (BatchErrorCollection[])(await DeleteNegativeKeywordsFromEntitiesAsync(
                    getNegativeKeywordsByEntityIdsResponse.EntityNegativeKeywords)).NestedPartialErrors;
                if (nestedPartialErrors == null || nestedPartialErrors.Length == 0)
                {
                    OutputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
                }
                else
                {
                    OutputBatchErrorCollections(nestedPartialErrors);
                }

                // Negative keywords can also be added and deleted from a shared negative keyword list. 
                // The negative keyword list can be shared or associated with multiple campaigns.
                // NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

                var negativeKeywordList = new NegativeKeywordList
                {
                    Name = "My Negative Keyword List" + DateTime.UtcNow,
                    Type = "NegativeKeywordList"
                };

                SharedListItem[] negativeKeywords = 
                {
                    new NegativeKeyword
                    {
                        Text = "car",
                        Type = "NegativeKeyword",
                        MatchType = MatchType.Exact
                    },
                    new NegativeKeyword
                    {
                        Text = "car",
                        Type = "NegativeKeyword",
                        MatchType = MatchType.Phrase
                    }
                };

                // You can create a new list for negative keywords with or without negative keywords.

                var addSharedEntityResponse = await AddSharedEntityAsync(negativeKeywordList, negativeKeywords);
                var sharedEntityId = addSharedEntityResponse.SharedEntityId;
                long[] listItemIds = addSharedEntityResponse.ListItemIds.ToArray();

                OutputStatusMessage(string.Format("NegativeKeywordList successfully added to account library and assigned identifer {0}\n", sharedEntityId));

                OutputNegativeKeywordsWithPartialErrors(
                    sharedEntityId,
                    negativeKeywords,
                    listItemIds,
                    addSharedEntityResponse.PartialErrors.ToArray());

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList { Id = sharedEntityId })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast<NegativeKeyword>());
                }

                // To update the list of negative keywords, you must either add or remove from the list
                // using the respective AddListItemsToSharedList or DeleteListItemsFromSharedList operations.
                // To remove the negative keywords from the list pass the negative keyword identifers
                // and negative keyword list (SharedEntity) identifer.

                var partialErrors = (await DeleteListItemsFromSharedListAsync(listItemIds, new NegativeKeywordList { Id = sharedEntityId }))?.PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage("Deleted most recently added negative keywords from negative keyword list.\n");

                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList { Id = sharedEntityId })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast<NegativeKeyword>());
                }

                // Whether you created the list with or without negative keywords, more can be added 
                // using the AddListItemsToSharedList operation.

                negativeKeywords = new SharedListItem[]
                {
                    new NegativeKeyword
                    {
                        Text = "auto",
                        Type = "NegativeKeyword",
                        MatchType = MatchType.Exact
                    },
                    new NegativeKeyword
                    {
                        Text = "auto",
                        Type = "NegativeKeyword",
                        MatchType = MatchType.Phrase
                    }
                };

                var addListItemsToSharedListResponse = await AddListItemsToSharedListAsync(
                    negativeKeywords,
                    new NegativeKeywordList { Id = sharedEntityId });
                listItemIds = addListItemsToSharedListResponse.ListItemIds.ToArray();

                OutputNegativeKeywordsWithPartialErrors(
                    sharedEntityId,
                    negativeKeywords,
                    listItemIds,
                    addListItemsToSharedListResponse.PartialErrors.ToArray());

                OutputStatusMessage("Negative keywords currently in NegativeKeywordList:");
                negativeKeywords = (SharedListItem[])(await GetListItemsBySharedListAsync(new NegativeKeywordList { Id = sharedEntityId })).ListItems;
                if (negativeKeywords == null || negativeKeywords.Length == 0)
                {
                    OutputStatusMessage("None\n");
                }
                else
                {
                    OutputNegativeKeywords(negativeKeywords.Cast<NegativeKeyword>());
                }

                // You can update the name of the negative keyword list. 

                negativeKeywordList = new NegativeKeywordList
                {
                    Id = sharedEntityId,
                    Name = "My Updated Negative Keyword List",
                    Type = "NegativeKeywordList"
                };

                partialErrors = (await UpdateSharedEntitiesAsync(new SharedEntity[] { negativeKeywordList })).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Updated Negative Keyword List Name to {0}.\n", negativeKeywordList.Name));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Get and output the negative keyword lists and store the list of identifiers.

                const string sharedEntityType = "NegativeKeywordList";
                var sharedEntities = (await GetSharedEntitiesByAccountIdAsync(sharedEntityType)).SharedEntities;
                OutputSharedEntityIdentifiersAsync(sharedEntities);
                var sharedEntityIds = new long[sharedEntities.Count];
                for (int index = 0; index < sharedEntities.Count; index++)
                {
                    if (sharedEntities[index].Id != null)
                    {
                        sharedEntityIds[index] = (long)sharedEntities[index].Id;
                    }
                }

                // Negative keywords were added to the negative keyword list above. You can associate the 
                // shared list of negative keywords with a campaign with or without negative keywords. 
                // Shared negative keyword lists cannot be associated with an ad group. An ad group can only 
                // be assigned an exclusive set of negative keywords. 

                var associations = new[]
                {
                    new SharedEntityAssociation
                    {
                        EntityId = campaignId,
                        EntityType = "Campaign",
                        SharedEntityId = sharedEntityId,
                        SharedEntityType = "NegativeKeywordList" 
                    }
                };

                partialErrors = (await SetSharedEntityAssociationsAsync(associations)).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Associated CampaignId {0} with Negative Keyword List Id {1}.\n",
                        campaignId, sharedEntityId));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Get and output the associations either by Campaign or NegativeKeywordList identifier.
                GetSharedEntityAssociationsByEntityIdsResponse getSharedEntityAssociationsByEntityIdsResponse =
                    await GetSharedEntityAssociationsByEntityIdsAsync(new[] { campaignId }, "Campaign", "NegativeKeywordList");
                OutputSharedEntityAssociations(getSharedEntityAssociationsByEntityIdsResponse.Associations);
                OutputPartialErrors(getSharedEntityAssociationsByEntityIdsResponse.PartialErrors);

                // Currently the GetSharedEntityAssociationsBySharedEntityIds operation accepts only one shared entity identifier in the list.
                GetSharedEntityAssociationsBySharedEntityIdsResponse getSharedEntityAssociationsBySharedEntityIdsResponse =
                    await GetSharedEntityAssociationsBySharedEntityIdsAsync("Campaign", new[] { sharedEntityIds[sharedEntityIds.Length - 1] }, "NegativeKeywordList");
                OutputSharedEntityAssociations(getSharedEntityAssociationsBySharedEntityIdsResponse.Associations);
                OutputPartialErrors(getSharedEntityAssociationsBySharedEntityIdsResponse.PartialErrors);

                // Explicitly delete the association between the campaign and the negative keyword list.

                partialErrors = (await DeleteSharedEntityAssociationsAsync(associations)).PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage("Deleted NegativeKeywordList associations\n");
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }

                // Delete the campaign and any remaining assocations. 

                await DeleteCampaignsAsync(authorizationData.AccountId, new[] { campaignId });
                OutputStatusMessage(string.Format("Deleted Campaign Id {0}\n", campaignId));

                // DeleteCampaigns does not delete the negative keyword list from the account's library. 
                // Call the DeleteSharedEntities operation to delete the shared entities.

                partialErrors = (await DeleteSharedEntitiesAsync(new SharedEntity[] { new NegativeKeywordList { Id = sharedEntityId } }))?.PartialErrors;
                if (partialErrors == null || !partialErrors.Any())
                {
                    OutputStatusMessage(string.Format("Deleted Negative Keyword List (SharedEntity) Id {0}\n", sharedEntityId));
                }
                else
                {
                    OutputPartialErrors(partialErrors);
                }
            }
            // 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.V11.CampaignManagement.AdApiFaultDetail> ex)
            {
                OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
            }
            catch (FaultException<Microsoft.BingAds.V11.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.V11.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.v11;

import java.rmi.*;

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

public class NegativeKeywords extends ExampleBase {

    static AuthorizationData authorizationData;
    static ServiceClient<ICampaignManagementService> CampaignService; 
    	
    public static void main(java.lang.String[] args) {
	 
        try
        {
            authorizationData = new AuthorizationData();
            authorizationData.setDeveloperToken(DeveloperToken);
            authorizationData.setAuthentication(new PasswordAuthentication(UserName, Password));
            authorizationData.setCustomerId(CustomerId);
            authorizationData.setAccountId(AccountId);

            CampaignService = new ServiceClient<ICampaignManagementService>(
                    authorizationData, 
                    API_ENVIRONMENT,
                    ICampaignManagementService.class);

            // Specify a campaign. 

            ArrayOfCampaign campaigns = new ArrayOfCampaign();
            Campaign campaign = new Campaign();
            campaign.setName("Summer Shoes " + System.currentTimeMillis());
            campaign.setDescription("Summer shoes line.");
            campaign.setBudgetType(BudgetLimitType.DAILY_BUDGET_STANDARD);
            campaign.setDailyBudget(50.00);
            campaign.setTimeZone("PacificTimeUSCanadaTijuana");
            campaigns.getCampaigns().add(campaign);
			
            // Add the campaign
			 
            AddCampaignsResponse addCampaignsResponse = addCampaigns(AccountId, campaigns);
            ArrayOfNullableOflong nullableCampaignIds = addCampaignsResponse.getCampaignIds();
            ArrayOfBatchError campaignErrors = addCampaignsResponse.getPartialErrors();
            outputCampaignsWithPartialErrors(campaigns, nullableCampaignIds, campaignErrors);
            
            ArrayOflong campaignIds = new ArrayOflong();
            campaignIds.getLongs().add(nullableCampaignIds.getLongs().get(0));
			
            // You may choose to associate an exclusive set of negative keywords to an individual campaign 
            // or ad group. An exclusive set of negative keywords cannot be shared with other campaigns 
            // or ad groups. This sample only associates negative keywords with a campaign.

            ArrayOfNegativeKeyword negativeKeywords = new ArrayOfNegativeKeyword();
            NegativeKeyword negativeKeyword = new NegativeKeyword();
            negativeKeyword.setMatchType(MatchType.PHRASE);
            negativeKeyword.setText("auto");
            negativeKeywords.getNegativeKeywords().add(negativeKeyword);

            ArrayOfEntityNegativeKeyword entityNegativeKeywords = new ArrayOfEntityNegativeKeyword();
            EntityNegativeKeyword entityNegativeKeyword = new EntityNegativeKeyword();
            entityNegativeKeyword.setEntityId(campaignIds.getLongs().get(0));
            entityNegativeKeyword.setEntityType("Campaign");
            entityNegativeKeyword.setNegativeKeywords(negativeKeywords);
            entityNegativeKeywords.getEntityNegativeKeywords().add(entityNegativeKeyword);

            AddNegativeKeywordsToEntitiesResponse addNegativeKeywordsToEntitiesResponse = 
                 addNegativeKeywordsToEntities(entityNegativeKeywords);
            if (addNegativeKeywordsToEntitiesResponse.getNestedPartialErrors() == null
                 || addNegativeKeywordsToEntitiesResponse.getNestedPartialErrors().getBatchErrorCollections().size() == 0)
            {
                    outputStatusMessage("Added an exclusive set of negative keywords to the Campaign.\n");
                    outputNegativeKeywordIds(addNegativeKeywordsToEntitiesResponse.getNegativeKeywordIds());
            }
            else
            {
                    outputBatchErrorCollections(addNegativeKeywordsToEntitiesResponse.getNestedPartialErrors());
            }

            GetNegativeKeywordsByEntityIdsResponse getNegativeKeywordsByEntityIdsResponse = 
                 getNegativeKeywordsByEntityIds(campaignIds, "Campaign", AccountId);
            if (getNegativeKeywordsByEntityIdsResponse.getPartialErrors() == null
                 || getNegativeKeywordsByEntityIdsResponse.getPartialErrors().getBatchErrors().size() == 0)
            {
                    outputStatusMessage("Retrieved an exclusive set of negative keywords for the Campaign.\n");
                    outputEntityNegativeKeywords(getNegativeKeywordsByEntityIdsResponse.getEntityNegativeKeywords());
            }
            else
            {
                    outputPartialErrors(getNegativeKeywordsByEntityIdsResponse.getPartialErrors());
            }

            // If you attempt to delete a negative keyword without an identifier the operation will
            // succeed but will return partial errors corresponding to the index of the negative keyword
            // that was not deleted. 
            ArrayOfBatchErrorCollection nestedPartialErrors = deleteNegativeKeywordsFromEntities(entityNegativeKeywords);
            if (nestedPartialErrors == null || nestedPartialErrors.getBatchErrorCollections().size() == 0)
            {
                    outputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
            }
            else
            {
                    outputStatusMessage("Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.\n");
                    outputBatchErrorCollections(nestedPartialErrors);
            }

            // Delete the negative keywords with identifiers that were returned above.
            nestedPartialErrors = deleteNegativeKeywordsFromEntities(
                 getNegativeKeywordsByEntityIdsResponse.getEntityNegativeKeywords());
            if (nestedPartialErrors == null || nestedPartialErrors.getBatchErrorCollections().size() == 0)
            {
                    outputStatusMessage("Deleted an exclusive set of negative keywords from the Campaign.\n");
            }
            else
            {
                    outputBatchErrorCollections(nestedPartialErrors);
            }

            // Negative keywords can also be added and deleted from a shared negative keyword list. 
            // The negative keyword list can be shared or associated with multiple campaigns.
            // NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

            NegativeKeywordList negativeKeywordList = new NegativeKeywordList();
            negativeKeywordList.setName("My Negative Keyword List " + System.currentTimeMillis());
            negativeKeywordList.setType("NegativeKeywordList");

            ArrayOfSharedListItem sharedListItems = new ArrayOfSharedListItem();
            NegativeKeyword negativeKeyword1 = new NegativeKeyword();
            negativeKeyword1.setText("car");
            negativeKeyword1.setType("NegativeKeyword");
            negativeKeyword1.setMatchType(MatchType.EXACT);
            sharedListItems.getSharedListItems().add(negativeKeyword1);
            NegativeKeyword negativeKeyword2 = new NegativeKeyword();
            negativeKeyword2.setText("car");
            negativeKeyword2.setType("NegativeKeyword");
            negativeKeyword2.setMatchType(MatchType.PHRASE);
            sharedListItems.getSharedListItems().add(negativeKeyword2);

            // You can create a new list for negative keywords with or without negative keywords.

            AddSharedEntityResponse addSharedEntityResponse = addSharedEntity(negativeKeywordList, sharedListItems);
            long sharedEntityId = addSharedEntityResponse.getSharedEntityId();
            ArrayOflong listItemIds = addSharedEntityResponse.getListItemIds();

            outputStatusMessage(String.format("NegativeKeywordList successfully added to account library and assigned identifer %d\n\n", sharedEntityId));

            outputNegativeKeywordIdsWithPartialErrors(
                 sharedEntityId,
                 sharedListItems, 
                 listItemIds, 
                 addSharedEntityResponse.getPartialErrors());

            outputStatusMessage("Negative keywords currently in NegativeKeywordList:");
            negativeKeywordList.setId(sharedEntityId);

            sharedListItems = getListItemsBySharedList(negativeKeywordList);
            if (sharedListItems == null || sharedListItems.getSharedListItems().size() == 0)
            {
                    outputStatusMessage("None\n");
            }
            else
            {
                    outputSharedListItems(sharedListItems);
            }             

            // To update the list of negative keywords, you must either add or remove from the list
            // using the respective AddListItemsToSharedList or DeleteListItemsFromSharedList operations.
            // To remove the negative keywords from the list pass the negative keyword identifers
            // and negative keyword list (SharedEntity) identifer.

            ArrayOfBatchError partialErrors = deleteListItemsFromSharedList(listItemIds, negativeKeywordList);
            if (partialErrors == null || partialErrors.getBatchErrors().size() == 0)
            {
                    outputStatusMessage("Deleted most recently added negative keywords from negative keyword list.\n");

            }
            else
            {
                    outputPartialErrors(partialErrors);
            }

            outputStatusMessage("Negative keywords currently in NegativeKeywordList:");
            sharedListItems = getListItemsBySharedList(negativeKeywordList);
            if (sharedListItems == null || sharedListItems.getSharedListItems().size() == 0)
            {
                    outputStatusMessage("None\n");
            }
            else
            {
                    outputSharedListItems(sharedListItems);
            }

            // Whether you created the list with or without negative keywords, more can be added 
            // using the AddListItemsToSharedList operation.

            sharedListItems = new ArrayOfSharedListItem();
            negativeKeyword1 = new NegativeKeyword();
            negativeKeyword1.setText("auto");
            negativeKeyword1.setType("NegativeKeyword");
            negativeKeyword1.setMatchType(MatchType.EXACT);
            sharedListItems.getSharedListItems().add(negativeKeyword1);
            negativeKeyword2 = new NegativeKeyword();
            negativeKeyword2.setText("auto");
            negativeKeyword2.setType("NegativeKeyword");
            negativeKeyword2.setMatchType(MatchType.PHRASE);
            sharedListItems.getSharedListItems().add(negativeKeyword2);

            AddListItemsToSharedListResponse addListItemsToSharedListResponse = addListItemsToSharedList(
                 sharedListItems,
                 negativeKeywordList);
            listItemIds = addListItemsToSharedListResponse.getListItemIds();

            outputNegativeKeywordIdsWithPartialErrors(
                 sharedEntityId,
                 sharedListItems, 
                 listItemIds, 
                 addListItemsToSharedListResponse.getPartialErrors());

            outputStatusMessage("Negative keywords currently in NegativeKeywordList:");
            sharedListItems = getListItemsBySharedList(negativeKeywordList);
            if (sharedListItems == null || sharedListItems.getSharedListItems().size() == 0)
            {
                    outputStatusMessage("None\n");
            }
            else
            {
                    outputSharedListItems(sharedListItems);
            }

            // You can update the name of the negative keyword list. 

            negativeKeywordList.setName("My Updated Negative Keyword List");
            negativeKeywordList.setType("NegativeKeywordList");

            ArrayOfSharedEntity sharedEntities = new ArrayOfSharedEntity();
            sharedEntities.getSharedEntities().add(negativeKeywordList);
            partialErrors = updateSharedEntities(sharedEntities);
            if (partialErrors == null || partialErrors.getBatchErrors().size() == 0)
            {
                    outputStatusMessage(String.format("Updated Negative Keyword List Name to %s.\n\n", negativeKeywordList.getName()));
            }
            else
            {
                    outputPartialErrors(partialErrors);
            }

            // Get and print the negative keyword lists and return the list of identifiers.

            final java.lang.String sharedEntityType = "NegativeKeywordList";
            sharedEntities = getSharedEntitiesByAccountId(sharedEntityType);
            outputSharedEntityIdentifiers(sharedEntities);
			
            ArrayOflong sharedEntityIds = new ArrayOflong();
            for (int index = 0; index < sharedEntities.getSharedEntities().size(); index++)
            {
                SharedEntity sharedEntity = sharedEntities.getSharedEntities().get(index);
                if (sharedEntity.getId() != null)
                {
                    sharedEntityIds.getLongs().add((long)sharedEntity.getId());
                }
            }
			    
            // Negative keywords were added to the negative keyword list above. You can associate the 
            // shared list of negative keywords with a campaign with or without negative keywords. 
            // Shared negative keyword lists cannot be associated with an ad group. An ad group can only 
            // be assigned an exclusive set of negative keywords. 

            ArrayOfSharedEntityAssociation associations = new ArrayOfSharedEntityAssociation();
            SharedEntityAssociation association = new SharedEntityAssociation();
            association.setEntityId(campaignIds.getLongs().get(0));
            association.setEntityType("Campaign");
            association.setSharedEntityId(sharedEntityId);
            association.setSharedEntityType("NegativeKeywordList");
            associations.getSharedEntityAssociations().add(association);

            partialErrors = setSharedEntityAssociations(associations);
            if (partialErrors == null || partialErrors.getBatchErrors().size() == 0)
            {
                    outputStatusMessage(String.format("Associated CampaignId %d with Negative Keyword List Id %d.\n\n", 
                             campaignIds.getLongs().get(0), sharedEntityId));
            }
            else
            {
                    outputPartialErrors(partialErrors);
            }

            // Get and print the associations either by Campaign or NegativeKeywordList identifier.
            GetSharedEntityAssociationsByEntityIdsResponse getSharedEntityAssociationsByEntityIdsResponse = 
                 getSharedEntityAssociationsByEntityIds(campaignIds, "Campaign", "NegativeKeywordList");
            outputSharedEntityAssociations(getSharedEntityAssociationsByEntityIdsResponse.getAssociations());
            outputPartialErrors(getSharedEntityAssociationsByEntityIdsResponse.getPartialErrors());

            // Get the associations of the most recently added shared entity.
            ArrayOflong associatedSharedEntityIds = new ArrayOflong();
            associatedSharedEntityIds.getLongs().add(sharedEntityIds.getLongs().get(sharedEntityIds.getLongs().size()-1));
            GetSharedEntityAssociationsBySharedEntityIdsResponse getSharedEntityAssociationsBySharedEntityIdsResponse = 
                 getSharedEntityAssociationsBySharedEntityIds("Campaign", associatedSharedEntityIds, "NegativeKeywordList");
            outputSharedEntityAssociations(getSharedEntityAssociationsBySharedEntityIdsResponse.getAssociations());
            outputPartialErrors(getSharedEntityAssociationsBySharedEntityIdsResponse.getPartialErrors());

            // Explicitly delete the association between the campaign and the negative keyword list.

            partialErrors = deleteSharedEntityAssociations(associations);
            if (partialErrors == null || partialErrors.getBatchErrors().size() == 0)
            {
                    outputStatusMessage("Deleted NegativeKeywordList associations\n");
            }
            else
            {
                    outputPartialErrors(partialErrors);
            }

            // Delete the campaign and any remaining assocations. 
			
            deleteCampaigns(AccountId, campaignIds);
            outputStatusMessage(String.format("Deleted CampaignId %d\n", campaignIds.getLongs().get(0)));
			
            // DeleteCampaigns does not delete the negative keyword list from the account's library. 
            // Call the DeleteSharedEntities operation to delete the shared entities.

            partialErrors = deleteSharedEntities(sharedEntities);
            if (partialErrors == null || partialErrors.getBatchErrors().size() == 0)
            {
                 outputStatusMessage(String.format("Deleted Negative Keyword List (SharedEntity) Id %d\n\n", sharedEntityId));
            }
            else
            {
                    outputPartialErrors(partialErrors);
            }

            outputStatusMessage("Program execution completed\n"); 
			 
            // Campaign Management service operations can throw AdApiFaultDetail.
            } catch (AdApiFaultDetail_Exception ex) {
                    outputStatusMessage("The operation failed with the following faults:\n");

                    for (AdApiError error : ex.getFaultInfo().getErrors().getAdApiErrors())
                    {
                            outputStatusMessage("AdApiError\n");
                            outputStatusMessage(String.format("Code: %d\nError Code: %s\nMessage: %s\n\n", error.getCode(), error.getErrorCode(), error.getMessage()));
                    }

            // Campaign Management service operations can throw ApiFaultDetail.
            } catch (ApiFaultDetail_Exception ex) {
                    outputStatusMessage("The operation failed with the following faults:\n");

                    for (BatchError error : ex.getFaultInfo().getBatchErrors().getBatchErrors())
                    {
                            outputStatusMessage(String.format("BatchError at Index: %d\n", error.getIndex()));
                            outputStatusMessage(String.format("Code: %d\nMessage: %s\n\n", error.getCode(), error.getMessage()));
                    }

                    for (OperationError error : ex.getFaultInfo().getOperationErrors().getOperationErrors())
                    {
                            outputStatusMessage("OperationError\n");
                            outputStatusMessage(String.format("Code: %d\nMessage: %s\n\n", error.getCode(), error.getMessage()));
                    }
            } catch (RemoteException ex) {
                 outputStatusMessage("Service communication error encountered: ");
                 outputStatusMessage(ex.getMessage());
                 ex.printStackTrace();
            } catch (Exception ex) {
                    outputStatusMessage("Error encountered: ");
                    outputStatusMessage(ex.getMessage());
                    ex.printStackTrace();
            }
	}

	//Adds one or more campaigns to the specified account.
	
	static AddCampaignsResponse addCampaigns(long accountId, ArrayOfCampaign campaigns) throws RemoteException, Exception
	{
	    AddCampaignsRequest request = new AddCampaignsRequest();
	    
	    // Set the request information.
	
	    request.setAccountId(accountId);
	    request.setCampaigns(campaigns);
	
	    return CampaignService.getService().addCampaigns(request);
	}
     
     // Deletes one or more campaigns from the specified account.

     static void deleteCampaigns(long accountId, ArrayOflong campaignIds) throws RemoteException, Exception
     {
    	 DeleteCampaignsRequest request = new DeleteCampaignsRequest();
         
         request.setAccountId(accountId);
         request.setCampaignIds(campaignIds);

         CampaignService.getService().deleteCampaigns(request);
     }

     // Adds list items such as negative keywords to the corresponding list.

     static AddListItemsToSharedListResponse addListItemsToSharedList(
    		 ArrayOfSharedListItem listItems, 
            SharedList sharedList) throws RemoteException, Exception
     {
    	 AddListItemsToSharedListRequest request = new AddListItemsToSharedListRequest();
         
         request.setListItems(listItems);
         request.setSharedList(sharedList);
         
         return CampaignService.getService().addListItemsToSharedList(request);
     }

     // Adds a shared entity such as a negative keyword list to the account's library. 
     // Lists in the account's library can be associated with any campaign within the account.

     static AddSharedEntityResponse addSharedEntity(
            SharedEntity sharedEntity,
            ArrayOfSharedListItem listItems) throws RemoteException, Exception
     {
    	 AddSharedEntityRequest request = new AddSharedEntityRequest();
         
         request.setSharedEntity(sharedEntity);
         request.setListItems(listItems);
         
         return CampaignService.getService().addSharedEntity(request);
     }

     // Deletes list items such as negative keywords from the corresponding list. 

     static ArrayOfBatchError deleteListItemsFromSharedList(
    		ArrayOflong listItemIds, 
            SharedList sharedList) throws RemoteException, Exception
     {
    	 DeleteListItemsFromSharedListRequest request = new DeleteListItemsFromSharedListRequest();
         
         request.setListItemIds(listItemIds);
         request.setSharedList(sharedList);
         
         return CampaignService.getService().deleteListItemsFromSharedList(request).getPartialErrors();
     }

     // Deletes shared entities such as negative keyword lists from the account's library.

     static ArrayOfBatchError deleteSharedEntities(ArrayOfSharedEntity sharedEntities) throws RemoteException, Exception
     {
    	 DeleteSharedEntitiesRequest request = new DeleteSharedEntitiesRequest();
         
         request.setSharedEntities(sharedEntities);
         
         return CampaignService.getService().deleteSharedEntities(request).getPartialErrors();
     }

     // Removes the association between a shared entity such as a negative keyword list and an entity such as a campaign. 

     static ArrayOfBatchError deleteSharedEntityAssociations(ArrayOfSharedEntityAssociation associations) throws RemoteException, Exception
     {
    	 DeleteSharedEntityAssociationsRequest request = new DeleteSharedEntityAssociationsRequest();
         
         request.setAssociations(associations);
         
         return CampaignService.getService().deleteSharedEntityAssociations(request).getPartialErrors();
     }

     // Gets the list items such as the negative keywords of a negative keyword list. 

     static ArrayOfSharedListItem getListItemsBySharedList(SharedList sharedList) throws RemoteException, Exception
     {
    	 GetListItemsBySharedListRequest request = new GetListItemsBySharedListRequest();
         
         request.setSharedList(sharedList);
         
         return CampaignService.getService().getListItemsBySharedList(request).getListItems();
     }

     // Gets the shared entities such as negative keyword lists from the account's library.  

     static ArrayOfSharedEntity getSharedEntitiesByAccountId(java.lang.String sharedEntityType) throws RemoteException, Exception
     {
    	 GetSharedEntitiesByAccountIdRequest request = new GetSharedEntitiesByAccountIdRequest();
         
         request.setSharedEntityType(sharedEntityType);
         
         return CampaignService.getService().getSharedEntitiesByAccountId(request).getSharedEntities();
     }

     // Gets associations between a campaign and a shared entity such as a negative keyword list. 
     // You can request associations by associated entity identifiers.

     static GetSharedEntityAssociationsByEntityIdsResponse getSharedEntityAssociationsByEntityIds(
    		ArrayOflong entityIds,
            java.lang.String entityType, 
            java.lang.String sharedEntityType) throws RemoteException, Exception
     {
    	 GetSharedEntityAssociationsByEntityIdsRequest request = new GetSharedEntityAssociationsByEntityIdsRequest();
         
         request.setEntityIds(entityIds);
         request.setEntityType(entityType);
         request.setSharedEntityType(sharedEntityType);
         
         return CampaignService.getService().getSharedEntityAssociationsByEntityIds(request);
     }

     // Gets associations between a campaign and a shared entity such as a negative keyword list. 
     // You can request associations by shared entity identifiers.

     static GetSharedEntityAssociationsBySharedEntityIdsResponse getSharedEntityAssociationsBySharedEntityIds(
            java.lang.String entityType, 
            ArrayOflong sharedEntityIds,
            java.lang.String sharedEntityType) throws RemoteException, Exception
     {
    	 GetSharedEntityAssociationsBySharedEntityIdsRequest request = new GetSharedEntityAssociationsBySharedEntityIdsRequest();
         
         request.setEntityType(entityType);
         request.setSharedEntityIds(sharedEntityIds);
         request.setSharedEntityType(sharedEntityType);
         
         return CampaignService.getService().getSharedEntityAssociationsBySharedEntityIds(request);
     }

     // Sets the association between a campaign and a shared entity such as a negative keyword list. 

     static ArrayOfBatchError setSharedEntityAssociations(ArrayOfSharedEntityAssociation associations) throws RemoteException, Exception
     {
    	 SetSharedEntityAssociationsRequest request = new SetSharedEntityAssociationsRequest();
         
         request.setAssociations(associations);
         
         return CampaignService.getService().setSharedEntityAssociations(request).getPartialErrors();
     }

     // Updates shared entities such as negative keyword lists within the account's library. 

     static ArrayOfBatchError updateSharedEntities(ArrayOfSharedEntity sharedEntities) throws RemoteException, Exception
     {
    	 UpdateSharedEntitiesRequest request = new UpdateSharedEntitiesRequest();
         
         request.setSharedEntities(sharedEntities);
         
         return CampaignService.getService().updateSharedEntities(request).getPartialErrors();
     }

     // Adds negative keywords to the specified campaign or ad group.  

     static AddNegativeKeywordsToEntitiesResponse addNegativeKeywordsToEntities(ArrayOfEntityNegativeKeyword entityNegativeKeywords) throws RemoteException, Exception
     {
    	 AddNegativeKeywordsToEntitiesRequest request = new AddNegativeKeywordsToEntitiesRequest();
         
         request.setEntityNegativeKeywords(entityNegativeKeywords);
         
         return CampaignService.getService().addNegativeKeywordsToEntities(request);
     }

     // Deletes negative keywords from the specified campaign or ad group.  

     static ArrayOfBatchErrorCollection deleteNegativeKeywordsFromEntities(ArrayOfEntityNegativeKeyword entityNegativeKeywords) throws RemoteException, Exception
     {
    	 DeleteNegativeKeywordsFromEntitiesRequest request = new DeleteNegativeKeywordsFromEntitiesRequest();
         
         request.setEntityNegativeKeywords(entityNegativeKeywords);
         
         return CampaignService.getService().deleteNegativeKeywordsFromEntities(request).getNestedPartialErrors();
     }

     // Gets the negative keywords that are only associated with the specified campaigns or ad groups.  

     static GetNegativeKeywordsByEntityIdsResponse getNegativeKeywordsByEntityIds(
    		ArrayOflong entityIds, 
            java.lang.String entityType, 
            long parentEntityId) throws RemoteException, Exception
     {
    	 GetNegativeKeywordsByEntityIdsRequest request = new GetNegativeKeywordsByEntityIdsRequest();
         
         request.setEntityIds(entityIds);
         request.setEntityType(entityType);
         request.setParentEntityId(parentEntityId);
         
         return CampaignService.getService().getNegativeKeywordsByEntityIds(request);
     }
 }
<?php

namespace Microsoft\BingAds\Samples\V11;

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

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

include "/../AuthHelper.php";
include "/CampaignManagementHelper.php";
include "/CustomerManagementHelper.php";

use SoapVar;
use SoapFault;
use Exception;

// Specify the Microsoft\BingAds\V11\CampaignManagement classes that will be used.
use Microsoft\BingAds\V11\CampaignManagement\Campaign;
use Microsoft\BingAds\V11\CampaignManagement\EntityNegativeKeyword;
use Microsoft\BingAds\V11\CampaignManagement\SharedEntityAssociation;
use Microsoft\BingAds\V11\CampaignManagement\SharedEntity;
use Microsoft\BingAds\V11\CampaignManagement\SharedList;
use Microsoft\BingAds\V11\CampaignManagement\SharedListItem;
use Microsoft\BingAds\V11\CampaignManagement\NegativeKeyword;
use Microsoft\BingAds\V11\CampaignManagement\NegativeKeywordList;
use Microsoft\BingAds\V11\CampaignManagement\BudgetLimitType;
use Microsoft\BingAds\V11\CampaignManagement\MatchType;

// 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\AuthHelper;
use Microsoft\BingAds\Samples\V11\CampaignManagementHelper;
use Microsoft\BingAds\Samples\V11\CustomerManagementHelper;

$GLOBALS['AuthorizationData'] = null;
$GLOBALS['Proxy'] = null;
$GLOBALS['CustomerProxy'] = null; 
$GLOBALS['CampaignProxy'] = null; 

// Disable WSDL caching.

ini_set("soap.wsdl_cache_enabled", "0");
ini_set("soap.wsdl_cache_ttl", "0");

try
{
    // You should authenticate for Bing Ads production services with a Microsoft Account, 
    // instead of providing the Bing Ads username and password set. 
    
    //AuthHelper::AuthenticateWithOAuth();

    // However, authentication with a Microsoft Account is currently not supported in Sandbox,
    // so it is recommended that you set the UserName and Password in sandbox for testing.

    AuthHelper::AuthenticateWithUserName();

    $GLOBALS['CustomerProxy'] = new ServiceClient(ServiceClientType::CustomerManagementVersion11, $GLOBALS['AuthorizationData'], AuthHelper::GetApiEnvironment());

    // Set the GetUser request parameter to an empty user identifier to get the current 
    // authenticated Bing Ads user, and then search for all accounts the user may access.

    $user = CustomerManagementHelper::GetUser(null)->User;

    // For this example we'll use the first account.

    $accounts = CustomerManagementHelper::SearchAccountsByUserId($user->Id)->Accounts;
    $GLOBALS['AuthorizationData']->AccountId = $accounts->Account[0]->Id;
    $GLOBALS['AuthorizationData']->CustomerId = $accounts->Account[0]->ParentCustomerId;

    $GLOBALS['CampaignProxy'] = new ServiceClient(ServiceClientType::CampaignManagementVersion11, $GLOBALS['AuthorizationData'], AuthHelper::GetApiEnvironment());

    // Specify one or more campaigns.
    
    $campaigns = array();
   
    $campaign = new Campaign();
    $campaign->Name = "Winter Clothing " . $_SERVER['REQUEST_TIME'];
    $campaign->Description = "Winter clothing line.";
    $campaign->BudgetType = BudgetLimitType::DailyBudgetStandard;
    $campaign->DailyBudget = 50.00;
    $campaign->TimeZone = "PacificTimeUSCanadaTijuana";

    $campaigns[] = $campaign;

    print "AddCampaigns\n";
    $addCampaignsResponse = CampaignManagementHelper::AddCampaigns($GLOBALS['AuthorizationData']->AccountId, $campaigns);
    $nillableCampaignIds = $addCampaignsResponse->CampaignIds->long;
    CampaignManagementHelper::OutputIds($nillableCampaignIds);
    if(isset($addCampaignsResponse->PartialErrors->BatchError)){
        CampaignManagementHelper::OutputPartialErrors($addCampaignsResponse->PartialErrors->BatchError);
    }

    // You may choose to associate an exclusive set of negative keywords to an individual campaign 
    // or ad group. An exclusive set of negative keywords cannot be shared with other campaigns 
    // or ad groups. This sample only associates negative keywords with a campaign.

    $negativeKeyword = new NegativeKeyword();
    $negativeKeyword->MatchType = MatchType::Phrase;
    $negativeKeyword->Text = "auto";
             
    $entityNegativeKeyword = new EntityNegativeKeyword();
    $entityNegativeKeyword->EntityId = $nillableCampaignIds[0];
    $entityNegativeKeyword->EntityType = "Campaign";
    $entityNegativeKeyword->NegativeKeywords = array($negativeKeyword);

    $addNegativeKeywordsToEntitiesResponse = CampaignManagementHelper::AddNegativeKeywordsToEntities(array($entityNegativeKeyword));
    if((count((array)$addNegativeKeywordsToEntitiesResponse->NestedPartialErrors) == 0) 
        || !is_array($addNegativeKeywordsToEntitiesResponse->NestedPartialErrors->BatchErrorCollection))
    {
        print "Added an exclusive set of negative keywords to the Campaign.\n\n";
        CampaignManagementHelper::OutputNegativeKeywordIds($addNegativeKeywordsToEntitiesResponse->NegativeKeywordIds->IdCollection);
    }
    else
    {
        CampaignManagementHelper::OutputBatchErrorCollections($addNegativeKeywordsToEntitiesResponse->NestedPartialErrors->BatchErrorCollection);
    }

    $getNegativeKeywordsByEntityIdsResponse = CampaignManagementHelper::GetNegativeKeywordsByEntityIds($nillableCampaignIds, "Campaign", $GLOBALS['AuthorizationData']->AccountId);
    if((count((array)$getNegativeKeywordsByEntityIdsResponse->PartialErrors) == 0) 
        || !is_array($getNegativeKeywordsByEntityIdsResponse->PartialErrors->BatchError))
    {
        print "Retrieved an exclusive set of negative keywords for the Campaign.\n\n";
        CampaignManagementHelper::OutputEntityNegativeKeywords($getNegativeKeywordsByEntityIdsResponse->EntityNegativeKeywords->EntityNegativeKeyword);
    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($getNegativeKeywordsByEntityIdsResponse->PartialErrors->BatchError);
    }
       
    // If you attempt to delete a negative keyword without an identifier the operation will
    // succeed but will return partial errors corresponding to the index of the negative keyword
    // that was not deleted. 
    $nestedPartialErrors = CampaignManagementHelper::DeleteNegativeKeywordsFromEntities(array($entityNegativeKeyword));
    if ((count((array)$nestedPartialErrors) == 0) || !is_array($nestedPartialErrors->BatchErrorCollection))
    {
        print "Deleted an exclusive set of negative keywords from the Campaign.\n\n";   
    }
    else
    {
        print "Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.\n\n";
        CampaignManagementHelper::OutputBatchErrorCollections($nestedPartialErrors->BatchErrorCollection);
    }

    // Delete the negative keywords with identifiers that were returned above.
    $nestedPartialErrors = CampaignManagementHelper::DeleteNegativeKeywordsFromEntities($getNegativeKeywordsByEntityIdsResponse->EntityNegativeKeywords->EntityNegativeKeyword);
    if ((count((array)$nestedPartialErrors) == 0) || !is_array($nestedPartialErrors->BatchErrorCollection))
    {
        print "Deleted an exclusive set of negative keywords from the Campaign.\n\n";
    }
    else
    {
        CampaignManagementHelper::OutputBatchErrorCollections($nestedPartialErrors->BatchErrorCollection);
    }

    // Negative keywords can also be added and deleted from a shared negative keyword list. 
    // The negative keyword list can be shared or associated with multiple campaigns.
    // NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

    $negativeKeywordList = new NegativeKeywordList();
    $negativeKeywordList->Name = "My Negative Keyword List";
    $negativeKeywordList->Type = "NegativeKeywordList";
    $encodedNegativeKeywordList = new SoapVar($negativeKeywordList, SOAP_ENC_OBJECT, 'NegativeKeywordList', $GLOBALS['CampaignProxy']->GetNamespace());

    $negativeKeywords = array();
    $negativeKeyword = new NegativeKeyword();
    $negativeKeyword->Text = "car";
    $negativeKeyword->Type = "NegativeKeyword";
    $negativeKeyword->MatchType = MatchType::Exact;
    $encodedNegativeKeyword = new SoapVar($negativeKeyword, SOAP_ENC_OBJECT, 'NegativeKeyword', $GLOBALS['CampaignProxy']->GetNamespace());
    $negativeKeywords[] = $encodedNegativeKeyword;

    $negativeKeyword = new NegativeKeyword();
    $negativeKeyword->Text = "car";
    $negativeKeyword->Type = "NegativeKeyword";
    $negativeKeyword->MatchType = MatchType::Phrase;
    $encodedNegativeKeyword = new SoapVar($negativeKeyword, SOAP_ENC_OBJECT, 'NegativeKeyword', $GLOBALS['CampaignProxy']->GetNamespace());
    $negativeKeywords[] = $encodedNegativeKeyword;

    // You can create a new list for negative keywords with or without negative keywords.
       
    $addSharedEntityResponse = CampaignManagementHelper::AddSharedEntity($encodedNegativeKeywordList, $negativeKeywords);
    $sharedEntityId = $addSharedEntityResponse->SharedEntityId;
    $listItemIds = $addSharedEntityResponse->ListItemIds;

    printf("NegativeKeywordList successfully added to account library and assigned identifer %d\n\n", $sharedEntityId);

    CampaignManagementHelper::OutputNegativeKeywordResults(
        $sharedEntityId,
        $negativeKeywords, 
        $listItemIds->long, 
        $addSharedEntityResponse->PartialErrors);

    print "Negative keywords currently in NegativeKeywordList:\n";
    $negativeKeywordList->Id = $sharedEntityId;
    $encodedNegativeKeywordList = new SoapVar($negativeKeywordList, SOAP_ENC_OBJECT, 'NegativeKeywordList', $GLOBALS['CampaignProxy']->GetNamespace());
    $negativeKeywords = CampaignManagementHelper::GetListItemsBySharedList($encodedNegativeKeywordList);

    if((count((array)$negativeKeywords) == 0) || !is_array($negativeKeywords->SharedListItem))
    {
        print "None\n\n";
    }
    else
    {
        CampaignManagementHelper::OutputNegativeKeywords($negativeKeywords->SharedListItem);
    }             

    // To update the list of negative keywords, you must either add or remove from the list
    // using the respective AddListItemsToSharedList or DeleteListItemsFromSharedList operations.
    // To remove the negative keywords from the list pass the negative keyword identifers
    // and negative keyword list (SharedEntity) identifer.

    $partialErrors = CampaignManagementHelper::DeleteListItemsFromSharedList($listItemIds, $encodedNegativeKeywordList);
    if((count((array)$partialErrors) == 0) || !is_array($partialErrors))
    {
        print "Deleted most recently added negative keywords from negative keyword list.\n\n";

    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($partialErrors);
    }
       
    print "Negative keywords currently in NegativeKeywordList:\n";
    $negativeKeywords = CampaignManagementHelper::GetListItemsBySharedList($encodedNegativeKeywordList);
    if((count((array)$negativeKeywords) == 0) || !is_array($negativeKeywords->SharedListItem))
    {
        print "None\n\n";
    }
    else
    {
        CampaignManagementHelper::OutputNegativeKeywords($negativeKeywords->SharedListItem);
    }
       
    // Whether you created the list with or without negative keywords, more can be added 
    // using the AddListItemsToSharedList operation.

    $negativeKeywords = array();
    $negativeKeyword = new NegativeKeyword();
    $negativeKeyword->Text = "auto";
    $negativeKeyword->Type = "NegativeKeyword";
    $negativeKeyword->MatchType = MatchType::Exact;
    $encodedNegativeKeyword = new SoapVar($negativeKeyword, SOAP_ENC_OBJECT, 'NegativeKeyword', $GLOBALS['CampaignProxy']->GetNamespace());
    $negativeKeywords[] = $encodedNegativeKeyword;

    $negativeKeyword = new NegativeKeyword();
    $negativeKeyword->Text = "auto";
    $negativeKeyword->Type = "NegativeKeyword";
    $negativeKeyword->MatchType = MatchType::Phrase;
    $encodedNegativeKeyword = new SoapVar($negativeKeyword, SOAP_ENC_OBJECT, 'NegativeKeyword', $GLOBALS['CampaignProxy']->GetNamespace());
    $negativeKeywords[] = $encodedNegativeKeyword;

    $addListItemsToSharedListResponse = CampaignManagementHelper::AddListItemsToSharedList(
        $negativeKeywords,
        $encodedNegativeKeywordList);
    $listItemIds = $addListItemsToSharedListResponse->ListItemIds;

    CampaignManagementHelper::OutputNegativeKeywordResults(
        $sharedEntityId,
        $negativeKeywords, 
        $listItemIds->long, 
        $addListItemsToSharedListResponse->PartialErrors);

    print "Negative keywords currently in NegativeKeywordList:\n";
    $negativeKeywords = CampaignManagementHelper::GetListItemsBySharedList($encodedNegativeKeywordList);
    if((count((array)$negativeKeywords) == 0) || !is_array($negativeKeywords->SharedListItem))
    {
        print "None\n\n";
    }
    else
    {
        CampaignManagementHelper::OutputNegativeKeywords($negativeKeywords->SharedListItem);
    }

    // You can update the name of the negative keyword list. 

    $negativeKeywordList->Name = "My Updated Negative Keyword List";
    $negativeKeywordList->Type = "NegativeKeywordList";
    $encodedNegativeKeywordList = new SoapVar($negativeKeywordList, SOAP_ENC_OBJECT, 'NegativeKeywordList', $GLOBALS['CampaignProxy']->GetNamespace());

    $partialErrors = CampaignManagementHelper::UpdateSharedEntities(array($encodedNegativeKeywordList));
    if((count((array)$partialErrors) == 0) || !is_array($partialErrors))
    {
        printf("Updated Negative Keyword List Name to %s.\n\n", $negativeKeywordList->Name);
    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($partialErrors);
    }

    // Get and print the negative keyword lists and return the list of identifiers.

    $sharedEntityType = "NegativeKeywordList";
    $sharedEntityIds = CampaignManagementHelper::GetAndOutputSharedEntityIdentifiers($sharedEntityType);
       
    // Negative keywords were added to the negative keyword list above. You can associate the 
    // shared list of negative keywords with a campaign with or without negative keywords. 
    // Shared negative keyword lists cannot be associated with an ad group. An ad group can only 
    // be assigned an exclusive set of negative keywords. 

    $associations = array();
    $association = new SharedEntityAssociation();
    $association->EntityId = $nillableCampaignIds[0];
    $association->EntityType = "Campaign";
    $association->SharedEntityId = $sharedEntityId;
    $association->SharedEntityType = "NegativeKeywordList";
    $associations[] = $association;

    $partialErrors = CampaignManagementHelper::SetSharedEntityAssociations($associations);
    if((count((array)$partialErrors) == 0) || !is_array($partialErrors))
    {
        printf("Associated CampaignId %d with Negative Keyword List Id %d.\n\n", $nillableCampaignIds[0], $sharedEntityId);
    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($partialErrors);
    }
       
    // Get and print the associations either by Campaign or NegativeKeywordList identifier.
    $getSharedEntityAssociationsByEntityIdsResponse = 
        CampaignManagementHelper::GetSharedEntityAssociationsByEntityIds(array($nillableCampaignIds[0]), "Campaign", "NegativeKeywordList");
    if(isset($getSharedEntityAssociationsByEntityIdsResponse->Associations) && 
       isset($getSharedEntityAssociationsByEntityIdsResponse->Associations->SharedEntityAssociation))
    {
        CampaignManagementHelper::OutputSharedEntityAssociations($getSharedEntityAssociationsByEntityIdsResponse->Associations->SharedEntityAssociation);
    }
    CampaignManagementHelper::OutputPartialErrors($getSharedEntityAssociationsByEntityIdsResponse->PartialErrors);
       
    $getSharedEntityAssociationsBySharedEntityIdsResponse = 
        CampaignManagementHelper::GetSharedEntityAssociationsBySharedEntityIds("Campaign", array($sharedEntityIds[count(array($sharedEntityIds))-1]), "NegativeKeywordList");
    if(isset($getSharedEntityAssociationsBySharedEntityIdsResponse->Associations) && 
       isset($getSharedEntityAssociationsBySharedEntityIdsResponse->Associations->SharedEntityAssociation))
    {
        CampaignManagementHelper::OutputSharedEntityAssociations($getSharedEntityAssociationsBySharedEntityIdsResponse->Associations->SharedEntityAssociation);
    }
    CampaignManagementHelper::OutputPartialErrors($getSharedEntityAssociationsBySharedEntityIdsResponse->PartialErrors);
       
    // Explicitly delete the association between the campaign and the negative keyword list.

    $partialErrors = CampaignManagementHelper::DeleteSharedEntityAssociations($associations);
    if((count((array)$partialErrors) == 0) || !is_array($partialErrors))
    {
        print "Deleted NegativeKeywordList associations\n\n";
    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($partialErrors);
    }
       
    // Delete the campaign and any remaining assocations. 

    CampaignManagementHelper::DeleteCampaigns($GLOBALS['AuthorizationData']->AccountId, array($nillableCampaignIds[0]));
    printf("Deleted CampaignId %d\n\n", $nillableCampaignIds[0]);

    // DeleteCampaigns does not delete the negative keyword list from the account's library. 
    // Call the DeleteSharedEntities operation to delete the shared entities.

    $partialErrors = CampaignManagementHelper::DeleteSharedEntities(array($encodedNegativeKeywordList));
    if((count((array)$partialErrors) == 0) || !is_array($partialErrors))
    {
        printf("Deleted Negative Keyword List (SharedEntity) Id %d\n\n", $sharedEntityId);
    }
    else
    {
        CampaignManagementHelper::OutputPartialErrors($partialErrors);
    }    
}
catch (SoapFault $e)
{
    // Output the last request/response.
	
    print "\nLast SOAP request/response:\n";
    printf("Fault Code: %s\nFault String: %s\n", $e->faultcode, $e->faultstring);
    print $GLOBALS['Proxy']->GetWsdl() . "\n";
    print $GLOBALS['Proxy']->GetService()->__getLastRequest()."\n";
    print $GLOBALS['Proxy']->GetService()->__getLastResponse()."\n";
	
    // Campaign Management service operations can throw AdApiFaultDetail.
    if (isset($e->detail->AdApiFaultDetail))
    {
        // Log this fault.

        print "The operation failed with the following faults:\n";

        $errors = is_array($e->detail->AdApiFaultDetail->Errors->AdApiError)
        ? $e->detail->AdApiFaultDetail->Errors->AdApiError
        : array('AdApiError' => $e->detail->AdApiFaultDetail->Errors->AdApiError);

        // If the AdApiError array is not null, the following are examples of error codes that may be found.
        foreach ($errors as $error)
        {
            print "AdApiError\n";
            printf("Code: %d\nError Code: %s\nMessage: %s\n", $error->Code, $error->ErrorCode, $error->Message);

            switch ($error->Code)
            {
                default:
                    print "Please see MSDN documentation for more details about the error code output above.\n";
                    break;
            }
        }
    }

    // Campaign Management service operations can throw ApiFaultDetail.
    elseif (isset($e->detail->EditorialApiFaultDetail))
    {
        // Log this fault.

        print "The operation failed with the following faults:\n";

        // If the BatchError array is not null, the following are examples of error codes that may be found.
        if (!empty($e->detail->EditorialApiFaultDetail->BatchErrors))
        {
            $errors = is_array($e->detail->EditorialApiFaultDetail->BatchErrors->BatchError)
            ? $e->detail->EditorialApiFaultDetail->BatchErrors->BatchError
            : array('BatchError' => $e->detail->EditorialApiFaultDetail->BatchErrors->BatchError);

            foreach ($errors as $error)
            {
                printf("BatchError at Index: %d\n", $error->Index);
                printf("Code: %d\nError Code: %s\nMessage: %s\n", $error->Code, $error->ErrorCode, $error->Message);

                switch ($error->Code)
                {
                    default:
                        print "Please see MSDN documentation for more details about the error code output above.\n";
                        break;
                }
            }
        }

        // If the EditorialError array is not null, the following are examples of error codes that may be found.
        if (!empty($e->detail->EditorialApiFaultDetail->EditorialErrors))
        {
            $errors = is_array($e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError)
            ? $e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError
            : array('BatchError' => $e->detail->EditorialApiFaultDetail->EditorialErrors->EditorialError);

            foreach ($errors as $error)
            {
                printf("EditorialError at Index: %d\n", $error->Index);
                printf("Code: %d\nError Code: %s\nMessage: %s\n", $error->Code, $error->ErrorCode, $error->Message);
                printf("Appealable: %s\nDisapproved Text: %s\nCountry: %s\n", $error->Appealable, $error->DisapprovedText, $error->PublisherCountry);

                switch ($error->Code)
                {
                    default:
                        print "Please see MSDN documentation for more details about the error code output above.\n";
                        break;
                }
            }
        }

        // If the OperationError array is not null, the following are examples of error codes that may be found.
        if (!empty($e->detail->EditorialApiFaultDetail->OperationErrors))
        {
            $errors = is_array($e->detail->EditorialApiFaultDetail->OperationErrors->OperationError)
            ? $e->detail->EditorialApiFaultDetail->OperationErrors->OperationError
            : array('OperationError' => $e->detail->EditorialApiFaultDetail->OperationErrors->OperationError);

            foreach ($errors as $error)
            {
                print "OperationError\n";
                printf("Code: %d\nError Code: %s\nMessage: %s\n", $error->Code, $error->ErrorCode, $error->Message);

                switch ($error->Code)
                {
                    default:
                        print "Please see MSDN documentation for more details about the error code output above.\n";
                        break;
                }
            }
        }
    }
}
catch (Exception $e)
{
    if ($e->getPrevious())
    {
        ; // Ignore fault exceptions that we already caught.
    }
    else
    {
        print $e->getCode()." ".$e->getMessage()."\n\n";
        print $e->getTraceAsString()."\n\n";
    }
}

?>
from auth_helper import *
from output_helper import *

# You must provide credentials in auth_helper.py.

def main(authorization_data):

    try:
        # Add a campaign that will later be associated with negative keywords. 

        campaigns=campaign_service.factory.create('ArrayOfCampaign')
        campaign=set_elements_to_none(campaign_service.factory.create('Campaign'))
        campaign.Name="Summer Shoes " + strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
        campaign.Description="Summer shoes line."
        campaign.BudgetType='DailyBudgetStandard'
        campaign.DailyBudget=10
        campaign.TimeZone='PacificTimeUSCanadaTijuana'
        campaign.Status='Paused'
        campaigns.Campaign.append(campaign)

        add_campaigns_response=campaign_service.AddCampaigns(
            AccountId=authorization_data.account_id,
            Campaigns=campaigns
        )
        campaign_ids={
            'long': add_campaigns_response.CampaignIds['long'] if add_campaigns_response.CampaignIds['long'] else None
        }
        output_status_message("Campaign Ids:")
        output_ids(campaign_ids)

        # You may choose to associate an exclusive set of negative keywords to an individual campaign 
        # or ad group. An exclusive set of negative keywords cannot be shared with other campaigns 
        # or ad groups. This example only associates negative keywords with a campaign.

        entity_negative_keywords=campaign_service.factory.create('ArrayOfEntityNegativeKeyword')
        entity_negative_keyword=set_elements_to_none(campaign_service.factory.create('EntityNegativeKeyword'))
        entity_negative_keyword.EntityId=campaign_ids['long'][0]
        entity_negative_keyword.EntityType="Campaign"
        negative_keywords=campaign_service.factory.create('ArrayOfNegativeKeyword')
        negative_keyword=campaign_service.factory.create('NegativeKeyword')
        negative_keyword.MatchType='Phrase'
        negative_keyword.Text="auto"
        negative_keywords.NegativeKeyword.append(negative_keyword)
        entity_negative_keyword.NegativeKeywords=negative_keywords
        entity_negative_keywords.EntityNegativeKeyword.append(entity_negative_keyword)

        add_negative_keywords_to_entities_response=campaign_service.AddNegativeKeywordsToEntities(
            EntityNegativeKeywords=entity_negative_keywords
        )

        output_negative_keyword_ids(add_negative_keywords_to_entities_response.NegativeKeywordIds)
        output_nested_partial_errors(add_negative_keywords_to_entities_response.NestedPartialErrors)

        if add_negative_keywords_to_entities_response.NestedPartialErrors is None \
        and len(add_negative_keywords_to_entities_response.NestedPartialErrors['BatchErrorCollection']) == 0:
            output_status_message("Added an exclusive set of negative keywords to the Campaign.\n")
            output_negative_keyword_ids(add_negative_keywords_to_entities_response.NegativeKeywordIds)
        else:
            output_nested_partial_errors(add_negative_keywords_to_entities_response.NestedPartialErrors)
        
        get_negative_keywords_by_entity_ids_response=campaign_service.GetNegativeKeywordsByEntityIds(
            EntityIds=campaign_ids, 
            EntityType="Campaign", 
            ParentEntityId=authorization_data.account_id
        )

        output_entity_negative_keywords(get_negative_keywords_by_entity_ids_response.EntityNegativeKeywords)
        output_partial_errors(get_negative_keywords_by_entity_ids_response.PartialErrors)

        if hasattr(get_negative_keywords_by_entity_ids_response.PartialErrors, 'BatchError'):
            output_partial_errors(get_negative_keywords_by_entity_ids_response.PartialErrors)
        else:
            output_status_message("Retrieved an exclusive set of negative keywords for the Campaign.\n")
            output_entity_negative_keywords(get_negative_keywords_by_entity_ids_response.EntityNegativeKeywords)
        '''
        if get_negative_keywords_by_entity_ids_response.PartialErrors is None \
        and len(get_negative_keywords_by_entity_ids_response.PartialErrors) == 0:
            output_status_message("Retrieved an exclusive set of negative keywords for the Campaign.\n")
            output_entity_negative_keywords(get_negative_keywords_by_entity_ids_response.EntityNegativeKeywords)
        else:
            output_partial_errors(get_negative_keywords_by_entity_ids_response.PartialErrors)
        '''
        # If you attempt to delete a negative keyword without an identifier the operation will
        # succeed but will return partial errors corresponding to the index of the negative keyword
        # that was not deleted. 
        nested_partial_errors=campaign_service.DeleteNegativeKeywordsFromEntities(
            EntityNegativeKeywords=entity_negative_keywords
        )

        if nested_partial_errors is None or len(nested_partial_errors) == 0:
            output_status_message("Deleted an exclusive set of negative keywords from the Campaign.\n")
        else:
            output_status_message("Attempt to DeleteNegativeKeywordsFromEntities without NegativeKeyword identifier partially fails by design.")
            output_nested_partial_errors(nested_partial_errors)

        # Delete the negative keywords with identifiers that were returned above.
        nested_partial_errors=campaign_service.DeleteNegativeKeywordsFromEntities(get_negative_keywords_by_entity_ids_response.EntityNegativeKeywords)
        if nested_partial_errors is None or len(nested_partial_errors) == 0:
            output_status_message("Deleted an exclusive set of negative keywords from the Campaign.\n")
        else:
            output_nested_partial_errors(nested_partial_errors)

        # Negative keywords can also be added and deleted from a shared negative keyword list. 
        # The negative keyword list can be shared or associated with multiple campaigns.
        # NegativeKeywordList inherits from SharedList which inherits from SharedEntity.

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Name="My Negative Keyword List " + strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
        negative_keyword_list.Type="NegativeKeywordList"
        
        negative_keywords=campaign_service.factory.create('ArrayOfSharedListItem')
        negative_keyword_1=set_elements_to_none(campaign_service.factory.create('NegativeKeyword'))
        negative_keyword_1.Text="car"
        negative_keyword_1.Type="NegativeKeyword"
        negative_keyword_1.MatchType='Exact'
        negative_keywords.SharedListItem.append(negative_keyword_1)
        negative_keyword_2=set_elements_to_none(campaign_service.factory.create('NegativeKeyword'))
        negative_keyword_2.Text="car"
        negative_keyword_2.Type="NegativeKeyword"
        negative_keyword_2.MatchType='Phrase'
        negative_keywords.SharedListItem.append(negative_keyword_2)

        # You can create a new list for negative keywords with or without negative keywords.

        add_shared_entity_response=campaign_service.AddSharedEntity(
            SharedEntity=negative_keyword_list, 
            ListItems=negative_keywords
        )
        shared_entity_id=add_shared_entity_response.SharedEntityId
        list_item_ids=add_shared_entity_response.ListItemIds

        output_status_message("NegativeKeywordList successfully added to account library and assigned identifer {0}\n".format(shared_entity_id))

        output_negative_keyword_results(
            shared_entity_id,
            negative_keywords,
            list_item_ids,
            add_shared_entity_response.PartialErrors
        )

        output_status_message("Negative keywords currently in NegativeKeywordList:")

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        negative_keywords=campaign_service.GetListItemsBySharedList(SharedList=negative_keyword_list)
        if negative_keywords is None or len(negative_keywords) == 0:
            output_status_message("None\n")
        else:
            output_negative_keywords(negative_keywords)

        # To update the list of negative keywords, you must either add or remove from the list
        # using the respective AddListItemsToSharedList or DeleteListItemsFromSharedList operations.
        # To remove the negative keywords from the list pass the negative keyword identifers
        # and negative keyword list (SharedEntity) identifer.

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        partial_errors=campaign_service.DeleteListItemsFromSharedList(
            ListItemIds=list_item_ids, 
            SharedList=negative_keyword_list
        )
        if partial_errors is None:
            output_status_message("Deleted most recently added negative keywords from negative keyword list.\n")
        else:
            output_partial_errors(partial_errors)

        output_status_message("Negative keywords currently in NegativeKeywordList:")

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        negative_keywords=campaign_service.GetListItemsBySharedList(SharedList=negative_keyword_list)
        if negative_keywords is None or len(negative_keywords) == 0:
            output_status_message("None\n")
        else:
            output_negative_keywords(negative_keywords)

        # Whether you created the list with or without negative keywords, more can be added 
        # using the AddListItemsToSharedList operation.

        negative_keywords=campaign_service.factory.create('ArrayOfSharedListItem')
        negative_keyword_1=set_elements_to_none(campaign_service.factory.create('NegativeKeyword'))
        negative_keyword_1.Text="auto"
        negative_keyword_1.Type="NegativeKeyword"
        negative_keyword_1.MatchType='Exact'
        negative_keywords.SharedListItem.append(negative_keyword_1)
        negative_keyword_2=set_elements_to_none(campaign_service.factory.create('NegativeKeyword'))
        negative_keyword_2.Text="auto"
        negative_keyword_2.Type="NegativeKeyword"
        negative_keyword_2.MatchType='Phrase'
        negative_keywords.SharedListItem.append(negative_keyword_2)

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id

        add_list_items_to_shared_list_response=campaign_service.AddListItemsToSharedList(
            ListItems=negative_keywords,
            SharedList=negative_keyword_list
        )
        list_item_ids=add_list_items_to_shared_list_response.ListItemIds

        output_negative_keyword_results(
            shared_entity_id,
            negative_keywords,
            list_item_ids,
            add_list_items_to_shared_list_response.PartialErrors
        )

        output_status_message("Negative keywords currently in NegativeKeywordList:")

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        negative_keywords=campaign_service.GetListItemsBySharedList(SharedList=negative_keyword_list)
        if negative_keywords is None or len(negative_keywords) == 0:
            output_status_message("None\n")
        else:
            output_negative_keywords(negative_keywords)

        # You can update the name of the negative keyword list. 

        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        negative_keyword_list.Name="My Updated Negative Keyword List"
        negative_keyword_list.Type="NegativeKeywordList"

        negative_keyword_lists=campaign_service.factory.create('ArrayOfSharedEntity')
        negative_keyword_list=set_elements_to_none(campaign_service.factory.create('NegativeKeywordList'))
        negative_keyword_list.Id=shared_entity_id
        negative_keyword_lists.SharedEntity.append(negative_keyword_list)
        partial_errors=campaign_service.UpdateSharedEntities(SharedEntities=negative_keyword_lists)
        if partial_errors is None:
            output_status_message("Updated Negative Keyword List Name to {0}.\n".format(negative_keyword_list.Name))
        else:
            output_partial_errors(partial_errors)

        # Get and print the negative keyword lists and return the list of identifiers.

        SHARED_ENTITY_TYPE="NegativeKeywordList"
        shared_entities=campaign_service.GetSharedEntitiesByAccountId(SharedEntityType=SHARED_ENTITY_TYPE)
        shared_entity_ids=[]
        if hasattr(shared_entities, 'SharedEntity'):
            index=0
            for shared_entity in shared_entities['SharedEntity']:
                shared_entity_ids.append(shared_entity.Id)
                output_status_message(
                    "SharedEntity[{0}] ({1}) has SharedEntity Id {2}.\n".format(
                        index,
                        shared_entity.Name,
                        shared_entity.Id
                    )
                )
                index=index+1

        # Negative keywords were added to the negative keyword list above. You can associate the 
        # shared list of negative keywords with a campaign with or without negative keywords. 
        # Shared negative keyword lists cannot be associated with an ad group. An ad group can only 
        # be assigned an exclusive set of negative keywords. 

        shared_entity_associations=campaign_service.factory.create('ArrayOfSharedEntityAssociation')
        shared_entity_association=set_elements_to_none(campaign_service.factory.create('SharedEntityAssociation'))
        shared_entity_association.EntityId=campaign_ids['long'][0]
        shared_entity_association.EntityType="Campaign"
        shared_entity_association.SharedEntityId=shared_entity_id
        shared_entity_association.SharedEntityType="NegativeKeywordList" 
        shared_entity_associations.SharedEntityAssociation.append(shared_entity_association)
        
        partial_errors=campaign_service.SetSharedEntityAssociations(Associations=shared_entity_associations)
        if partial_errors is None:
            output_status_message(
                "Associated CampaignId {0} with Negative Keyword List Id {1}.\n".format(campaign_ids['long'][0], shared_entity_id)
            )
        else:
            output_partial_errors(partial_errors)

        # Get and print the associations either by Campaign or NegativeKeywordList identifier.
        get_shared_entity_associations_by_entity_ids_response=campaign_service.GetSharedEntityAssociationsByEntityIds(
            EntityIds=campaign_ids, 
            EntityType="Campaign", 
            SharedEntityType="NegativeKeywordList"
        )
        output_shared_entity_associations(get_shared_entity_associations_by_entity_ids_response.Associations)
        output_partial_errors(get_shared_entity_associations_by_entity_ids_response.PartialErrors)

        # Currently the GetSharedEntityAssociationsBySharedEntityIds operation accepts only one shared entity identifier in the list.
        get_shared_entity_associations_by_shared_entity_ids_response=campaign_service.GetSharedEntityAssociationsBySharedEntityIds(
            EntityType="Campaign", 
            SharedEntityIds={'long': [shared_entity_ids[len(shared_entity_ids) - 1]]}, 
            SharedEntityType="NegativeKeywordList"
        )
        output_shared_entity_associations(get_shared_entity_associations_by_shared_entity_ids_response.Associations)
        output_partial_errors(get_shared_entity_associations_by_shared_entity_ids_response.PartialErrors)

        # Explicitly delete the association between the campaign and the negative keyword list.

        partial_errors=campaign_service.DeleteSharedEntityAssociations(Associations=shared_entity_associations)
        if partial_errors is None:
            output_status_message("Deleted NegativeKeywordList associations\n")
        else:
            output_partial_errors(partial_errors)

        # Delete the campaign and any remaining assocations. 

        campaign_service.DeleteCampaigns(
            AccountId=authorization_data.account_id,
            CampaignIds=campaign_ids
        )

        for campaign_id in campaign_ids['long']:
            output_status_message("Deleted CampaignId {0}\n".format(campaign_id))

        # DeleteCampaigns does not delete the negative keyword list from the account's library. 
        # Call the DeleteSharedEntities operation to delete the shared entities.

        negative_keyword_lists=campaign_service.factory.create('ArrayOfSharedEntity')
        negative_keyword_list=campaign_service.factory.create('NegativeKeywordList')
        negative_keyword_list.Id=shared_entity_id
        negative_keyword_lists.SharedEntity.append(negative_keyword_list)
        partial_errors=campaign_service.DeleteSharedEntities(SharedEntities=negative_keyword_lists)
        if partial_errors is None:
            output_status_message("Deleted Negative Keyword List (SharedEntity) Id {0}\n".format(shared_entity_id))
        else:
            output_partial_errors(partial_errors)

        output_status_message("Program execution completed")

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

# Main execution
if __name__ == '__main__':

    print("Python loads the web service proxies at runtime, so you will observe " \
          "a performance delay between program launch and main execution...\n")
    
    authorization_data=AuthorizationData(
        account_id=None,
        customer_id=None,
        developer_token=DEVELOPER_TOKEN,
        authentication=None,
    )

    campaign_service=ServiceClient(
        service='CampaignManagementService', 
        authorization_data=authorization_data, 
        environment=ENVIRONMENT,
        version=11,
    )

    # You should authenticate for Bing Ads production services with a Microsoft Account, 
    # instead of providing the Bing Ads username and password set. 
    # Authentication with a Microsoft Account is currently not supported in Sandbox.
        
    authenticate(authorization_data)
        
    main(authorization_data)

See Also

Get Started with the Bing Ads API