A changing offer in a webshop with many products and brands means that you regularly have to check for exclusions in the non-branded campaigns. Then use this script to ensure that all brands that are in your shop are automatically excluded in non-branded campaigns. The script runs through all brands in the feed and checks whether they are in the list of negative words. If this is not the case, it will be added as a phrase.

Settings

  • LOG: Specify whether the script should report the intermediate steps, by adjusting the value to 'true'.
  • LIST_NAME: The name of the negative keyword list
  • PRODUCT_FEED_URL: Enter the URL of the XML product feed as it appears in Google Merchant Center
Script
// Copyright 2019. Increase BV. All Rights Reserved.
//
// Created By: Tibbe van Asten
// for Increase B.V.
// 
// Created: 05-06-2019
// Last update: 18-06-2019
//
// ABOUT THE SCRIPT
// This script will check the feed, collect all brandnames and add
// them to a negative keyword list. 
//
////////////////////////////////////////////////////////////////////

var config = {
 
  LOG : true,
  
  // The name of the Negative Keyword List
  LIST_NAME : "Brands",
  
  // To make use of this script, we connect the productfeed
  PRODUCT_FEED_URL : "PRODUCT_FEED_URL.xml",

}

////////////////////////////////////////////////////////////////////

function main(){
  
  var brands = connectFeed();
  
  // Get negative keyword lists with LIST_NAME
  var negativeKeywordListIterator = AdsApp
  	.negativeKeywordLists()
  	.withCondition("Name CONTAINS '" + config.LIST_NAME + "'")
  	.get();
  
  while(negativeKeywordListIterator.hasNext()){
    var negativeKeywordList = negativeKeywordListIterator.next();
    var negativeKeywords = collectNegativeKeywords(negativeKeywordList);
    
    // Remove brackets and quotationmarks from the keywords
    // to match them to brandnames in the feed
    var negativeKeywordsStripped = [];
    
    	if(config.LOG === true){
          Logger.log("List: " + negativeKeywordList.getName());
          Logger.log("Negatives: " + negativeKeywords);
          Logger.log("Brands: " + brands);
          Logger.log(" ");
        }
    
    // Create stripped list of brandnames
    for(var x = 0;x < negativeKeywords.length;x++){      
      var negativeKeyword = negativeKeywords[x].getText().replace(/\[/g,"").replace(/\]/g,"");
      negativeKeywordsStripped.push(negativeKeyword);     
    } // negativeKeywords iterator
    
    // Add brands when not in the negative keyword list
    for(var y = 0;y < brands.length;y++){
      
      if(negativeKeywordsStripped.indexOf('"' + brands[y] + '"') < 0){
        negativeKeywordList.addNegativeKeyword('"' + brands[y] + '"'); 

        if(config.LOG === true){
          Logger.log("Added " + brands[y] + " to " + negativeKeywordList.getName());
        }
      }

    } // queryIterator 
    
    Logger.log(" ");    
    
  } // negativeKeywordListIterator  
  
} // function main

////////////////////////////////////////////////////////////////////

function connectFeed(){
  
  var brands = [];
  
    if(config.PRODUCT_FEED_URL == "PRODUCT_FEED_URL.xml"){
      throw error("Update your productfeed URL in the config");
    }
  
  // Connect to the feed with the URL from the config
  var xml = UrlFetchApp.fetch(config.PRODUCT_FEED_URL).getContentText();
  var document = XmlService.parse(xml);
  var entries = document.getRootElement().getChild('channel').getChildren('item');
  var atom = XmlService.getNamespace('http://base.google.com/ns/1.0');  
  
  for (var i = 1; i < entries.length; i++) { 
    
    // When the brandname is not in the list already, we'll add it
	if(brands.indexOf(entries[i].getChild('brand', atom).getValue().toLowerCase()) < 0){
    	brands.push(entries[i].getChild('brand', atom).getValue().toLowerCase());
    }
      
  } // for statement
  
  return brands;
  
} // function connectFeed()
  
////////////////////////////////////////////////////////////////////

function collectNegativeKeywords(negativeKeywordList){
  
  var negativeKeywords = [];
  
  var negativeKeywordIterator = negativeKeywordList
    .negativeKeywords()
    .get();

  while(negativeKeywordIterator.hasNext()){
    negativeKeywords.push(negativeKeywordIterator.next());
  } // negativeKeywordIterator
  
  return negativeKeywords;
  
} // collectNegativeKeywords

Sharing Knowledge

Adsscripts.com is all about sharing knowledge. In the current market, PPC specialists like to keep their knowledge and experience to themselves. We're convinced that sharing knowledge can ensure that everyone gets better at their work. We want to change this by sharing our knowledge about scripts with everyone.

Do you also want to contribute? We are open to new ideas and feedback on everything you find on Adsscripts.com.

Contact us

Nils Rooijmans
Google Ads Scripter
Water Cooler Topics
Nils Rooijmans, Google Ads Scripter
Bas Baudoin
Teamleader PPC
Happy Leads
Bas Baudoin, Teamleader PPC
Martijn Kraan
Freelance PPC Specialist
Brightstep
Martijn Kraan, Freelance PPC Specialist
Tibbe van Asten
PPC Specialist
Founder Adsscripts
Tibbe van Asten, Senior PPC Automation Specialist