Google Ads Negative Keywords Automation with AI

FlowHunt's AI-driven tool automates Google Ads negative keyword management, enhancing ROI by excluding irrelevant search terms. It uses real-time data to optimize ad spending, automate keyword updates, and improve campaign efficiency.

Last modified on November 26, 2024 at 3:09 am
Google Ads Negative Keywords Automation with AI

Running a Google Ads campaign requires more than just setting up ads and leaving them to perform. One of the main issues advertisers face is spending money on keywords that aren’t useful. When campaigns aren’t optimized for the right keywords, businesses end up paying for clicks that don’t lead to sales, causing financial losses. Managing keywords effectively is key to making sure your ad budget is spent wisely, maximizing your return on investment (ROI).

Wasting money on unwanted keywords in PPC campaigns
Example shows wasted budget for clicks on our ads from negative keywords (added as negative later)

Understanding Unwanted Keyword Spend
Unwanted keyword spend happens when your ads appear in search results that don’t match what you’re selling. This can quickly deplete your budget, as each irrelevant click costs money without leading to a sale. For example, if a company selling high-end leather shoes targets broad keywords like “buy shoes,” it might attract clicks from people interested in sneakers or sandals, which aren’t what they offer. This mismatch in keyword targeting can lead to wasted ad spend and lower ROI. Businesses need to grasp this concept to avoid unnecessary financial losses and focus their budget on the right keywords.

The Role of Negative Keywords
Negative keywords are an essential tool in any Google Ads campaign. They let advertisers exclude specific search terms from triggering their ads, ensuring that only relevant searches lead to ad views. For example, using negative keywords like “cheap” or “discount” can help the leather shoe company avoid clicks from people not interested in premium products. By carefully crafting a list of negative keywords, businesses can optimize their ad spending, reduce unwanted clicks, and boost their campaign’s overall effectiveness.

Using AI for Keyword Management
Artificial Intelligence (AI) is changing how advertisers manage Google Ads campaigns. AI tools like FlowHunt are made for keyword grouping, helping businesses identify and organize related keywords more effectively. This automation simplifies the process of finding both positive and negative keywords, cutting down on the manual work involved in managing campaigns. AI-driven keyword management allows for real-time changes based on performance data, ensuring that ad spending is continually optimized for the best ROI.

Strategies to Reduce Unwanted Keyword Spend
To cut down on unwanted keyword spending, businesses should adopt several strategies. First, it’s important to regularly update your keyword list to match changing market trends and consumer interests. Implementing a strong negative keyword strategy is also crucial; this involves constantly researching and updating the list of terms you want to exclude. Additionally, monitoring and tweaking campaigns based on performance data is vital. By analyzing which keywords lead to sales and which don’t, businesses can make informed decisions to refine their targeting and get the most out of their ad spend.

Case Study: PostAffiliatePro’s Approach
PostAffiliatePro was facing issues with their monthly ad spending, struggling to get the ROI they wanted from their Google Ads campaigns. They decided to use AI to address this problem. By incorporating AI-driven tools, they automated their keyword management process, identifying both positive and negative keywords more accurately. This change allowed them to optimize their ad spending, significantly cutting costs and improving campaign efficiency. Their experience highlights the benefits of using AI technology to manage keyword spending effectively. Analyses of each new keyword are running within a hour from the first impression of the keyword. The speed helps us to catch negative keywords before visitors could click in the Google Ad.

improved conversion rate
Improved conversion rate (Just relevant search brings more sales)

Additional Resources
For those interested in learning more about effective keyword management and AI optimization, consider exploring these resources:

Google Ads Script to evaluate each new keyword

Here is our script, which we run each hour to evaluate keyword clusters.
This script aims to automate several tasks related to managing Google Ads campaigns. It interacts with Google Sheets for configuration and settings, and performs operations on Google Ads accounts, like analyzing search terms, adding or excluding keywords, and interfacing with the FlowHunt API for advanced AI keyword clustering.

Google Sheet to manage script settings
Negative keywords automatically applied to Ad groups

Main Function

– The core control logic is housed in the `main()` function. This function opens the Google Sheets document specified by `spreadsheetURL`, retrieves necessary configuration settings like `apiKey`, `country`, `language`, and others.

– Initially, the system attempts to add any new positive keywords to the FlowHunt cluster. If successful, it proceeds to analyze any unassigned search terms.

Keyword Analysis

Analyzing Not Assigned Words: function iterates over all ad groups within the Ads account marked with a specific label. It retrieves search terms from Google Ads that are not currently targeted and had minimum one impression. The system uses the FlowHunt API to find similar keywords to currently analyzed keyword, filtering them based on a specified `minimumMatch` criterion. Search terms that match the criteria are either added as positive keywords or marked as negatives if minimum criteria are not matched, updating the relevant Google Sheet with this information and also updating your Google Ads campaigns.

FlowHunt Integration

API Interaction: The script relies on the function `callFlowHuntApi()` to interact with the FlowHunt API for various tasks, including retrieving workspace IDs and clustering keywords.

Add Keywords to Cluster: This function pushes positive keywords back to FlowHunt for clustering, ensuring they’re informed by live search query data from Google Ads.

Added and negative keywords are logged into separate sheets for ongoing tracking and review.

Usage

To deploy this script, users need to:

– Provide a valid Google Sheets URL and ensure necessary sheets (“Settings”, “AddedKW”, “NegativeKW”) are present.

– Configure the Google Sheets with correct FlowHunt API key, country codes, and other operational settings.

– Ensure the script is executed within a Google Ads Script environment with proper API access enabled.

Add script to your Google Ads in menu Tools -> Bulk Actions -> Scripts.

Don’t forget to set the real link to your Google Sheet document. The rest is our magic. We identify keywords, which belong to the campaign and automate the management of keywords (Both negative or positive).

Google Ads script to automatically manage negative keywords

//Global variables
var spreadsheetURL;
var spreadsheet;
var sheetSettings; 
var sheetAddedKW;
var sheetNegativeKW;
var apiKey;
var labelName;
var country;
var language;
var location;
var urlsCount;
var minimumMatch;
var workspaceId;


function main() {
    // Provide the Google Sheets URL here
  spreadsheetURL = "https://docs.google.com/spreadsheets/d/....... FULL URL TO GOOGLE SHEET";
  spreadsheet = SpreadsheetApp.openByUrl(spreadsheetURL);
  sheetSettings = spreadsheet.getSheetByName("Settings"); 
  sheetAddedKW = spreadsheet.getSheetByName("AddedKW");
  sheetNegativeKW = spreadsheet.getSheetByName("NegativeKW");
  apiKey = getSettingValue("FlowHuntAPIkey")
  labelName = getSettingValue("LabelName")
  country = getSettingValue("CountryCode")
  language = getSettingValue("LanguageCode")
  location = getSettingValue("Location")

  urlsCount = getSettingValue("TopUrlsCount")
  minimumMatch = getSettingValue("MinimumMatch")
  workspaceId = getWorkspaceId()
  
  if (workspaceId.length < 10) {
    Logger.log("Failed to load workspace id from FlowHunt, check API key");
    return;
  }
  
  Logger.log("FlowHunt WorkspaceId: " + workspaceId);
  
  if (addPositiveKWsToCluster() == 0) {
    // Analyze new keywords just if all positive keywords added already
    analyzeNotAssignedWords();
  }
}


function analyzeNotAssignedWords() {
  Logger.log("*** START Checking not assigned keywords");
  
  
  // Iterate through all ad groups in the account
  var adGroupsIterator = AdsApp.adGroups().get();
  
  while (adGroupsIterator.hasNext()) {
    var adGroup = adGroupsIterator.next();
    var groupName = adGroup.getId() + " - " + adGroup.getName();
    if (hasLabel(adGroup, labelName)) {
      
            // Get the search terms for the current ad group ordered by clicks in the last X days
      var searchTermsQuery = "SELECT Query FROM SEARCH_QUERY_PERFORMANCE_REPORT " +
        "WHERE AdGroupId = " + adGroup.getId() +
        " AND QueryTargetingStatus = \"NONE\" " +
        "DURING TODAY";

      var searchTermsIterator = AdsApp.report(searchTermsQuery).rows();
      var adGroupKeywords = [];
      while (searchTermsIterator.hasNext()) {
        var searchTerm = searchTermsIterator.next();
        var searchTermText = searchTerm["Query"].trim();
        var similarQueries = getSimilarQueries(groupName, searchTermText)
        var filteredSimilarQueries = getFilteredSimilarQueries(similarQueries);
        if (filteredSimilarQueries.length > 0) {
          var keywordOperation = adGroup.newKeywordBuilder().withText("[" + searchTermText + "]").build();
          if (keywordOperation.isSuccessful()) {
            adGroupKeywords.push(searchTermText);
            var rowData = [groupName, searchTermText, new Date(), "ADDING AS POSITIVE, REVIEW!", JSON.stringify(filteredSimilarQueries)];
            sheetAddedKW.appendRow(rowData);
          } else {
            Logger.log("Failed to add keyword as positive:" + searchTermText)
          }
        } else {
          // add to negative
           adGroup.createNegativeKeyword("[" + searchTermText + "]");
          Logger.log("Excluded search term in ad group '" + groupName + "': " + searchTermText);
          var rowData = [groupName, "[" + searchTermText + "]", new Date(), JSON.stringify(similarQueries)];
          sheetNegativeKW.appendRow(rowData);
        }
      }
      if (adGroupKeywords.length > 0) {
        //Add all keywords in the list to FlowHunt Cluster
        addKeywordsToFlowHunt(groupName, adGroupKeywords);
      }
    }
  }
  Logger.log("*** FINISHED Checking not assigned keywords");
}

function getSimilarQueries(groupName, query) {
  result = callFlowHuntApi("/serp/serp/cluster/query_intersections?workspace_id="+workspaceId, "POST", {
    "query": query,
    "country": country,
    "language": language,
    "location": location,
    "group_name": groupName,
    "live_mode": true,
    "max_position": urlsCount
  });
  Logger.log(result)
  if (result.status=="SUCCESS") {
    return JSON.parse(result.result);
  }
  return []
}

function getFilteredSimilarQueries(similarQueries) {
  filtered = [];
  for (var i=1; i<similarQueries.length; i++){
    if (similarQueries[i].count>=minimumMatch) {
      filtered.push(similarQueries[i]);
    }
  }
  return filtered;
}

function addPositiveKWsToCluster() {
  Logger.log("*** START Checking new campaign keywords");
  // Iterate through all ad groups in the account
  var adGroupsIterator = AdsApp.adGroups().get();
  var processedKWs = sheetAddedKW.getDataRange().getValues();
  var processedKWsMap = {};
  var rowsAdded = 0;
  
  for (var i = 1; i < processedKWs.length; i++) { // Start at 1 to skip header row if exists
    var groupName = processedKWs[i][0];
    var keyword = processedKWs[i][1];
    processedKWsMap[groupName + '|' + keyword] = true;
  }
  
  
  while (adGroupsIterator.hasNext()) {
    var adGroup = adGroupsIterator.next();
    var groupName = adGroup.getId() + " - " + adGroup.getName();
    if (hasLabel(adGroup, labelName)) {
      var keywordsIterator = adGroup.keywords().get();
      var adGroupKeywords = [];
      while (keywordsIterator.hasNext()) {
        var keyword = keywordsIterator.next();
        if (keyword.isEnabled()) {
          var key = groupName + '|' + keyword.getText();
          if (!processedKWsMap[key]) {
            adGroupKeywords.push(keyword.getText());
            var rowData = [groupName, keyword.getText(), new Date(), "Already present in campaign"];
            sheetAddedKW.appendRow(rowData);
            processedKWsMap[key] = true; 
          }
        }
      }
      if (adGroupKeywords.length > 0) {
        //Add all keywords in the list to FlowHunt Cluster
        addKeywordsToFlowHunt(groupName, adGroupKeywords);
      } else {
        Logger.log("No new keywords in Group: " + groupName);
      }
      rowsAdded = rowsAdded + adGroupKeywords.length
    }
  }
  Logger.log("*** FINISHED Checking new campaign keywords");
  return rowsAdded;
}


function addKeywordsToFlowHunt(GroupName, adGroupKeywords) {
  requests = []
  adGroupKeywords.forEach(function(keyword) {
    requests.push(
        {
          "query": keyword,
          "country": country,
          "language": language,
          "location": location,
          "group_name": GroupName,
          "count_urls": 30
        }
      );
    });
  callFlowHuntApi("/serp/serp/cluster/add_queries?workspace_id="+workspaceId, "POST", {"requests":requests});
}


function getSettingValue(settingName) {
    var data = sheetSettings.getDataRange().getValues();
    for (var i = 0; i < data.length; i++) {
        if (data[i][0] === settingName) {
            return data[i][1];
        }
    }
    return null;
}
  
  
function getWorkspaceId() {
  result = callFlowHuntApi("/auth/me", "GET")
  if (result !== null) {
    return result.api_key_workspace_id;
  }
}


function callFlowHuntApi(endpoint, method, requestBody) {
    var url = "https://api.flowhunt.io/v2" + endpoint;
    var headers = {
        "Api-Key": apiKey,
        "Content-Type": "application/json"
    };
    var options = {
        "method" : method,  // or "post", "put", etc.
        "headers" : headers,
        "payload": JSON.stringify(requestBody)
    };
    
    try {
        var response = UrlFetchApp.fetch(url, options);
        var responseData = JSON.parse(response.getContentText());
        Logger.log(responseData);
        return responseData;
    } catch (e) {
        Logger.log("An error occurred: " + e.message);
    }
    return null;
}

function hasLabel(adGroup, labelName) {
  var labels = adGroup.labels().get();
  while (labels.hasNext()) {
    var label = labels.next();
    if (label.getName() === labelName) {
      Logger.log("Processing Adgroup " + adGroup.getName());
      return true;
    }
  }
  return false;
}

Conclusion

Active keyword management is essential for businesses aiming to maximize their ROI from Google Ads campaigns. By understanding the impact of unwanted keyword spending and using tools like negative keywords and AI-driven management, companies can greatly reduce financial losses. Embracing these strategies not only improves campaign efficiency but also ensures that every dollar spent on ads contributes to generating valuable conversions.

Are you interested to automate your own Google Ads with AI? Contact us and we setup everything for you.

Discover how a Webpage Content GAP Analysis can boost your SEO by identifying missing elements in your content. Learn to enhance your webpage's ranking with actionable insights and competitor comparisons. Visit FlowHunt for more details.

Webpage Content GAP Analysis

Boost your SEO with FlowHunt's Webpage Content GAP Analysis. Identify content gaps, enhance ranking potential, and refine your strategy.

Discover FlowHunt's AI-driven templates for chatbots, content creation, SEO, and more. Simplify your workflow with powerful, specialized tools today!

Templates

Discover FlowHunt's AI-driven templates for chatbots, content creation, SEO, and more. Simplify your workflow with powerful, specialized tools today!

Generate perfect SEO titles effortlessly with FlowHunt's Web Page Title Generator. Input your keyword and let AI create optimized titles for you!

Web Page Title Generator Template

Generate perfect SEO titles effortlessly with FlowHunt's Web Page Title Generator. Just input a keyword and get top-performing titles in seconds!

Learn from the top-ranking content on Google. This Tool will generate high-quality, SEO-optimized content inspired by the best.

Top Pages Content Generator

Generate high-quality, SEO-optimized content by analyzing top-ranking Google pages with FlowHunt's Top Pages Content Generator. Try it now!

Our website uses cookies. By continuing we assume your permission to deploy cookies as detailed in our privacy and cookies policy.