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).
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.
Additional Resources
For those interested in learning more about effective keyword management and AI optimization, consider exploring these resources:
- Google’s official guide on using negative keywords: Google Support Page
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.
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.
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.
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!