Automatic Search Terms Excluder for Shopping

The script automatically excludes search terms in shopping campaigns that don't contain selected keywords.

Start Now!
Automatic excluding Search Terms for Shopping
Automatic Get started!

Suppose we are selling remote controls for televisions. It's obvious that we want the search terms to include the word "remote". Without it, users might just be looking to buy a tv (not a remote). Especially if the search term report indicates many phrases containing only tv models.

This is exactly the situation where the following Google Ads script can help.

Our tasks as PPC managers are:

  1. Verify shopping campaigns.
    We look for situations where the absence of a certain keyword means that the search terms lose value for us and don't generate conversions.
  2. Choose this word and insert it into the script configuration. In the above example, it would be the word: "remote".

All search terms that don't contain this phrase will be automatically added as exclusions in exact match.

Configuration

  1. Insert the required word into the REQUIRED_KEYWORDS variable. We can add an infinite number of words. Each should be in quotes and separated by a comma.
  2. Insert the label name into the variable: CAMPAIGN_LABEL. Label the selected campaign(s)
  3. Schedule the script to run once daily in the morning.

Note: The script only makes changes in shopping campaigns.

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:
const REQUIRED_KEYWORDS = ["YOUR KEYWORD HERE"];
const CAMPAIGN_LABEL = "YOUR LABEL HERE";
// --------------------------------------- End of the configuration

function main() {
    ensureLabelExists();
    const campaignIds = getEnabledShoppingCampaignIds();
    const queriesToAddAsNegative = findNegativeKeywordCandidates(campaignIds);

    if (queriesToAddAsNegative.length > 0) {
        Logger.log(`Adding ${queriesToAddAsNegative.length} new negative keywords...`);
        addNegativeKeywordsToCampaign(queriesToAddAsNegative);
    } else {
        Logger.log("No negative keyword additions required.");
    }
}

function getEnabledShoppingCampaignIds() {
    const campaignIds = [];
    const campaignSelector = AdsApp.shoppingCampaigns()
        .withCondition(`LabelNames CONTAINS_ANY ['${CAMPAIGN_LABEL}']`)
        .withCondition("Status = ENABLED");

    const campaigns = campaignSelector.get();
    while (campaigns.hasNext()) {
        const campaign = campaigns.next();
        campaignIds.push(campaign.getId());
    }

    return campaignIds;
}

function findNegativeKeywordCandidates(campaignIds) {
    const negativeCandidates = [];
    const queryReport = AdsApp.report(
        'SELECT Query FROM SEARCH_QUERY_PERFORMANCE_REPORT ' +
        'WHERE CampaignId IN [' + campaignIds.join(",") + '] ' +
        'DURING YESTERDAY');

    const rows = queryReport.rows();
    while (rows.hasNext()) {
        const row = rows.next();
        const query = row['Query'];
        if (isNegativeKeywordCandidate(query)) {
            negativeCandidates.push(query);
        }
    }

    return negativeCandidates;
}

function isNegativeKeywordCandidate(query) {
    return REQUIRED_KEYWORDS.some(requiredWord => !query.includes(requiredWord));
}

function addNegativeKeywordsToCampaign(negativeQueries) {
    const campaignIterator = AdsApp.shoppingCampaigns()
        .withCondition(`LabelNames CONTAINS_ANY ['${CAMPAIGN_LABEL}']`)
        .get();

    if (campaignIterator.hasNext()) {
        const campaign = campaignIterator.next();
        Logger.log(`Selected campaign: ${campaign.getName()}`);
        negativeQueries.forEach(query => {
            campaign.createNegativeKeyword(`[${query}]`);
            Logger.log(`${query} --> added as an exact negative keyword`);
        });
    }
}

function ensureLabelExists() {
    const labelIterator = AdsApp.labels().withCondition(`Name = '${CAMPAIGN_LABEL}'`).get();
    if (!labelIterator.totalNumEntities()) {
        AdsApp.createLabel(CAMPAIGN_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