Keywords Meanings Controller

Exclude keywords from your campaigns, when they don't match what you meant for.

Start Now!
Keyword meaning controller
Keywords Get started!

Some time ago, Google introduced a new concept of keyword matching: by meanings.

In practice, ads may now show for a variety of searches that include a meaning of the keyword. Despite our use of the exact match type, they can be only very loosely related to what we wanted.

Let's imagine you have a keyword: [cheap car accessories]. You don't want it to trigger your ads for "car fire extinguishers" or "car sponges" because maybe you don't sell them at all.

The goal of this script is to make sure selected keywords don't show for meanings if you don't want them to.

In this case, add "car accessories" in the script settings. Plus, add a label to all keywords that you want to control.

Each time the script finds queries that don't match your requirements, it'll add them as exact negative keywords at the ad group level.

Configuration

  1. Insert the required word into the REQUIRED_KEYWORDS variable.
  2. Insert the label name into the variable: KEYWORD_LABEL.
  3. Label the selected keyword(s).
  4. Schedule the script to run once daily in the morning.
The script
/*
Copyright 2024 Krzysztof Bycina, www.LiveAds.pro
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// --------------------------------------- Configuration:
var REQUIRED_KEYWORDS = ["YOUR KEYWORD HERE""];
var KEYWORD_LABEL = "YOUR LABEL HERE";
// --------------------------------------- End of the configuration


function main() {
    checkLabel();
    var adGroupIds = findKeywordAdGroupIds();
    var badQueries = findBadQueries(adGroupIds);
    if (badQueries.length > 0) {
        Logger.log("The script adds " + badQueries.length + " new negative keywords...");
        addNegativeKeywordsToSearch(badQueries, adGroupIds);
    } else {
        Logger.log("All search queries meet your requirements.");
    }
}

function findKeywordAdGroupIds() {
    var adGroupIds = [];
    var keywordsSelector = AdsApp.keywords()
        .withCondition("LabelNames CONTAINS_ANY ['" + KEYWORD_LABEL + "']")
        .withCondition("Status = ENABLED")
        .forDateRange("TODAY");
    var keywordsIterator = keywordsSelector.get();
    while (keywordsIterator.hasNext()) {
        var adGroupId = keywordsIterator.next().getAdGroup().getId();
        if (adGroupIds.indexOf(adGroupId) === -1) { 
            adGroupIds.push(adGroupId);
        }
    }
    return adGroupIds;
}

function findBadQueries(adGroupIds) {
    var badQueries = [];
    var report = AdsApp.report(
        'SELECT Query,Clicks,Impressions,Cost,Conversions,AdGroupId ' +
        'FROM SEARCH_QUERY_PERFORMANCE_REPORT ' +
        'WHERE AdGroupId IN [' + adGroupIds.join(",") + '] ' +
        'DURING YESTERDAY');
    var rows = report.rows();
    while (rows.hasNext()) {
        var isItBadQuery = true;
        var row = rows.next();
        var query = row['Query'];
        var length = REQUIRED_KEYWORDS.length;
        while (length--) {
            if (query.indexOf(REQUIRED_KEYWORDS[length]) != -1) {
                isItBadQuery = false;
            }
        }
        if (isItBadQuery) {
            badQueries.push(row['Query']);
        }
    }
    return badQueries;
}

function addNegativeKeywordsToSearch(badQueries, adGroupIds) {
    adGroupIds.forEach(function(adGroupId) {
        var adGroup = AdsApp.adGroups()
            .withIds([adGroupId])
            .get()
            .next();

        Logger.log("Selected ad group: " + adGroup.getName());
        badQueries.forEach(function(badQuery) {
            adGroup.createNegativeKeyword('[' + badQuery + ']');
            Logger.log(badQuery + " --> added as an exact negative keyword.");
        });
    });
}

function checkLabel() {
    var labelIterator = AdsApp.labels().withCondition("Name = '" + KEYWORD_LABEL + "'").get();
    if (!labelIterator.totalNumEntities()) {
        AdsApp.createLabel(KEYWORD_LABEL);
    }
}
Show whole script!
Loading Comments
The Experts
Tibbe van Asten Team Lead Performance Marketing
Nils Rooijmans Water Cooler Topics
Martijn Kraan Freelance PPC Specialist
Bas Baudoin Teamlead SEA @ Happy Leads
Jermaya Leijen Digital Marketing Strategist
Krzysztof Bycina PPC Specialist from Poland
How about you? JOIN US!
Sharing Knowledge
Caring

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

Training &
Workshop
Contact us!
Adsscripts Training & Workshop