Dit script kijkt naar alle zoektermen in campagnes om te zorgen dat te dure zoektermen automatisch uitgesloten worden. Omdat de gewenste CPA per campagne kan verschillen, werken we in dit script met labels. Door het toepassen van een label op een campagne en daarin de gewenste CPA te vermelden, worden te dure zoekwoorden gevonden.

Wanneer een zoekterm in een campagne gelijk is aan het bijbehorende zoekwoord, zan niet de zoekterm uitgesloten worden, maar de zoekterm gepauzeerd. Daarnaast kan het natuurlijk voorkomen dat zoekwoorden langer zijn dan 10 woorden, waardoor deze niet exact uitgesloten kunnen worden. Daarom worden zoektermen van langer dan 10 woorden ingekort tot 10 woorden en als zinsdeel uitgesloten.

Instellingen

Er valt voor dit scripts weinig in te stellen, behalve het volgende:

  • LOG: Geef aan of het script de tussenstappen moet rapporteren, door de waarde aan te passen naar 'true'.
  • THRESHOLD_MULTIPLIER: Deze variabele is van toepassing op zoektermen zonder conversies. Wanneer deze zoektermen kosten hebben die hoger zijn dan (gewenste CPA * deze variabele) worden ze uitgesloten. Zo kan je zoektermen de kans geven meer uit te geven dan de gewenste CPA om toch een conversie te behalen.
Script
// Copyright 2019. Increase BV. All Rights Reserved.
//
// Created By: Tibbe van Asten
// for Increase B.V.
// 
// Last update: 03-01-2019
//
// ABOUT THE SCRIPT
// With this script you can exclude search queries with  
// a high CPA. Each search queries must have at least
// one conversion to be excluded. You can set the 
// threshold multiplier yourself. 
//
////////////////////////////////////////////////////////////////////

var config = {

	LOG : false,
  
  	// Search queries will only be excluded when the CPA is at least [target CPA] * THRESHOLD_MULTIPLIER. 
  	// For example: When your target CPA is €5 and you set the threshold multiplier to 1.5,
  	// the search query will only be excluded when the CPA is over €5 * 1.5 = €7.5
	THRESHOLD_MULTIPLIER : 2

}

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

function main() {
  
  var campaignIterator = AdsApp
    .campaigns()
  	.withCondition("Status = ENABLED")
  	.get();

  while (campaignIterator.hasNext()) {
    var campaign = campaignIterator.next();
    findQueries(campaign);
  }
  
  var shoppingCampaignIterator = AdsApp
    .shoppingCampaigns()
  	.withCondition("Status = ENABLED")
  	.get();

  while (shoppingCampaignIterator.hasNext()) {
    var campaign = shoppingCampaignIterator.next();
    findQueries(campaign);
  }  
  
  Logger.log("Thanks for using this custom script. Visit https://increase.nl for more information.");
  
} // function main()

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

function findQueries(campaign) {  
    
    var labelIterator = campaign
    	.labels()
    	.withCondition("Name CONTAINS 'CPA'")
    	.withCondition("Name DOES_NOT_CONTAIN '_'")
    	.get();
  
    while (labelIterator.hasNext()) {
      var label = labelIterator.next();
      var targetCpa = label.getName().split(" ")[1];

      var THRESHOLD_CPA = (Math.round((targetCpa * config.THRESHOLD_MULTIPLIER) * 100) / 100) * 1000000;

      var report = AdsApp.report(
      "SELECT Query, Conversions, CostPerConversion, KeywordTextMatchingQuery, AdGroupId, AdGroupName, KeywordId, Cost " +
      "FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
      "WHERE CampaignStatus = ENABLED AND CampaignId = " + campaign.getId() +
      " AND AdGroupStatus = ENABLED" +
      " AND QueryTargetingStatus = NONE" +
      " AND Cost > " + THRESHOLD_CPA
      );

        var rows = report.rows();
        while (rows.hasNext()) {
          var row = rows.next();

          if(row["Conversions"] == 0 && row["Cost"] > (targetCpa * config.THRESHOLD_MULTIPLIER) || row["Conversions"] > 0.99 && row["CostPerConversion"] > (targetCpa * config.THRESHOLD_MULTIPLIER)) {
            
            Logger.log("-----");
            Logger.log(campaign.getName());
            Logger.log("Target CPA: " + targetCpa);
            Logger.log("-----");

            var query = "";

              if (row["Query"].split(" ").length < 10) {
                query = "[" + row["Query"] + "]";
              } else {
                for (var i = 0; (i < row["Query"].split(" ").length) && (i < 10); i++){ 
                  query += row["Query"].split(" ")[i] + " ";                 
                }
                query = '"' + query.replace(/\s+$/,'') + '"';
              }

				if(config.LOG === true){
                  Logger.log("Query: " + row["Query"]); 
                  Logger.log("Clean Query: " + query); 
                  Logger.log("Keyword: " + row["KeywordTextMatchingQuery"]); 
                  Logger.log("KeywordId: " + row["KeywordId"]); 
                }

            if (row["Query"] == row["KeywordTextMatchingQuery"]) {   
              	var ids = [];
              	var adgroupId = row["AdGroupId"];
              	var keywordId = row["KeywordId"];
              	ids.push([adgroupId, keywordId]);
                var keywordIterator = AdsApp
                  .keywords()
                  .withIds(ids)
                  .withCondition("Status = ENABLED")
                  .get();

                while (keywordIterator.hasNext()) {
                  var keyword = keywordIterator.next();
                  keyword.pause();
                    Logger.log("Conversions: " + row["Conversions"]); 
                    Logger.log("Cost: " + row["Cost"]); 
                    Logger.log("CostPerConversion: " + row["CostPerConversion"]);   
                    Logger.log("Keyword paused: " + row["KeywordTextMatchingQuery"]);
                  	Logger.log(" ");
                }                
            } 
            
            else{    
              var ids = [row["AdGroupId"]];
              var adGroupIterator = AdsApp
                .adGroups()
                .withIds(ids)
                .get();

              while (adGroupIterator.hasNext()) {
                var adGroup = adGroupIterator.next();
                adGroup.createNegativeKeyword(query);
                  Logger.log("Conversions: " + row["Conversions"]); 
                  Logger.log("Cost: " + row["Cost"]); 
                  Logger.log("CostPerConversion: " + row["CostPerConversion"]);   
                  Logger.log("Query excluded: " + query + " in " + row["AdGroupName"]);
                  Logger.log(" ");
              }              
            } 

          } // row selector
        } // row iterator
    } // label iterator
  
} // function findQueries(campaign)

Kennis delen

Adsscripts.com staat voor het delen van kennis. In de huidige markt houden SEA-specialisten de kennis en ervaring graag voor zich. Wij zijn er van overtuigd dat het delen van kennis ervoor kan zorgen dat iedereen beter wordt in haar of zijn werk. Daarom lopen wij hier graag in voorop, door onze kennis over scripts te delen met iedereen.

Wil jij ook graag een bijdrage leveren? Wij staan open voor nieuwe ideeën en feedback op alles wat je op Adsscripts.com vindt.

Neem contact op

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