
PPC AI Agent with Negative queries automation
Automate negative keywords in Google Ads with FlowHunt's PPC AI Agent. Exclude irrelevant queries, reduce wasted spend, and improve conversions with AI-driven t...
FlowHunt automates Google Ads negative keyword management with AI, helping businesses cut costs, optimize ad spend, and improve campaign results effortlessly.
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.
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.
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.
To cut down on unwanted keyword spending, businesses should adopt several strategies:
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 an hour from the first impression of the keyword. The speed helps to catch negative keywords before visitors could click in the Google Ad.
For those interested in learning more about effective keyword management and AI optimization, consider exploring these resources:
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.
main()
function. This function opens the Google Sheets document specified by spreadsheetURL
, retrieves necessary configuration settings like apiKey
, country
, language
, and others.minimumMatch
criterion.callFlowHuntApi()
to interact with the FlowHunt API for various tasks, including retrieving workspace IDs and clustering keywords.To deploy this script, users need to:
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).
//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;
}
Negative keywords prevent your ads from appearing for irrelevant searches, reducing wasted spend and improving campaign ROI by focusing only on the most relevant queries.
AI tools like FlowHunt analyze real-time search data, identify irrelevant keywords, and automatically update your campaigns with negative keywords, saving time and boosting efficiency.
Expect increased conversion rates, reduced ad spend on irrelevant clicks, and more efficient campaigns as AI continuously optimizes your keyword lists and targeting.
You'll need to connect your Google Ads account, configure settings in a Google Sheet, and deploy the provided script to enable automated keyword management powered by FlowHunt's AI.
Viktor Zeman is a co-owner of QualityUnit. Even after 20 years of leading the company, he remains primarily a software engineer, specializing in AI, programmatic SEO, and backend development. He has contributed to numerous projects, including LiveAgent, PostAffiliatePro, FlowHunt, UrlsLab, and many others.
Ready to maximize your Google Ads ROI? Discover how AI-powered automation manages your negative keywords and optimizes ad spend.
Automate negative keywords in Google Ads with FlowHunt's PPC AI Agent. Exclude irrelevant queries, reduce wasted spend, and improve conversions with AI-driven t...
Discover how PPC management automation and advanced keyword optimization strategies can double your conversion rates, reduce ad spend, and streamline your campa...
Learn how to optimize PPC campaigns and master keyword grouping for higher relevance, improved Quality Scores, better ROI, and effective campaign management. Di...