Alert for PMax Search Terms

Receive an alert by email with all metrics for selected search terms in PMax

Start Now!
PMax Alerts for selected search terms
Alert for Get started!

 

One of the biggest challenges in Performance Max campaign management is understanding the search intent that leads to a click.
It wasn't even possible before. Thankfully, Google allowed us to view this data recently.

This tool utilizes the new functionality.
It's different from other scripts like that PMax Search Terms report.

My solution doesn’t export any data to spreadsheets.
It's an alerting system that sends an email with all metrics for selected search terms in PMax.

Key use cases

a) Monitor brand terms: This way, you'll know if PMax is cannibalizing your brand campaign.
b) Monitor competition in PMax: This way, you'll know if PMax is bidding heavily on your competition (not always a good idea!).
c) Monitor poorly performing terms: You can look at search or standard campaigns and find top-spending search terms with low ROAS or high CPA and add them to the script.

Configuration

  1. Insert the desired keywords into the UNWANTED_SEARCH_TERMS variable.
    An unlimited number of keywords may be added.
    Enclose each one in quotation marks and separate them with commas.
  2. Insert the label name into the variable: campaign_label.
  3. Label the selected Performance Max campaign.

Schedule: daily or weekly (I prefer Monday morning).

 

The script
/*
Copyright 2023 Krzysztof Bycina, www.LiveAds.pl
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 UNWANTED_SEARCH_TERMS = ["ENTER YOUR KEYWORD HERE e.g. BRAND NAME"];
const CAMPAIGN_LABEL = "ENTER YOUR LABEL HERE";
const EMAIL = "ENTER YOUR E-MAIL HERE";
// --------------------------------------- End of the configuration


function main() {
    const campaigns = fetchCampaigns();
    const matches = [];

    campaigns.forEach(campaign => {
        const id = campaign.id;
        const name = campaign.name;

        const queries = retrieveQueries(id);
        const matchingRows = inspectCampaign(queries, name);

        if (matchingRows.length > 0) {
            matches.push({
                campaignName: name,
                matchingRows: matchingRows
            });
        }
    });

    if (matches.length > 0) {
        notifyByEmail(matches);
    }
}

function retrieveQueries(id) {
    const query = AdsApp.report(`
    SELECT 
    campaign_search_term_insight.category_label,
    metrics.clicks, 
    metrics.impressions, 
    metrics.conversions,
    metrics.conversions_value
    FROM campaign_search_term_insight 
    WHERE 
    segments.date DURING LAST_30_DAYS 
    AND campaign_search_term_insight.campaign_id = '${id}'
    ORDER BY metrics.conversions
    `);

    return query;
}

function inspectCampaign(query, campaignName) {
    const data = [];
    const rows = query.rows();

    while (rows.hasNext()) {
        const row = rows.next();
        const rowData = {
            campaign_name: campaignName,
            category_label: row['campaign_search_term_insight.category_label'],
            clicks: row['metrics.clicks'],
            impressions: row['metrics.impressions'],
            conversions: row['metrics.conversions'],
            conversions_value: row['metrics.conversions_value']
        };

        data.push(rowData);
    }

    const matchingRows = data.filter(row => {
        return UNWANTED_SEARCH_TERMS.some(term => row.category_label.includes(term));
    });

    console.log("PMax campaigns with unwanted search terms: '" + campaignName + "':", matchingRows);
    return matchingRows;
}

function notifyByEmail(matches) {
    const subject = "PMax search terms alert summary.";
    let message = "PMax campaigns with unwanted search terms:\n\n";
    let totalClicks = 0;
    let totalImpressions = 0;
    let totalConversions = 0;
    let totalConversionsValue = 0;
    matches.forEach(match => {
        const campaignName = match.campaignName;
        const matchingRows = match.matchingRows;
        matchingRows.forEach(row => {
            const clicks = parseInt(row.clicks);
            const impressions = parseInt(row.impressions);
            totalClicks += clicks;
            totalImpressions += impressions;
            totalConversions += parseFloat(row.conversions);
            totalConversionsValue += parseFloat(row.conversions_value);
            message += "Campaign: " + campaignName + "\n\n";
            message += "Category Label: " + row.category_label + "\n";
            message += "Clicks: " + clicks + "\n";
            message += "Impressions: " + impressions + "\n";
            message += "Conversions: " + parseFloat(row.conversions).toFixed(2) + "\n";
            message += "Conversions Value: " + parseFloat(row.conversions_value).toFixed(2) + "\n\n";
        });
        message += "---------------------------------------------------\n\n";
    });
    totalConversions = totalConversions.toFixed(2);
    totalConversionsValue = totalConversionsValue.toFixed(2);
    message = `Total Clicks: ${totalClicks}\n` +
        `Total Impressions: ${totalImpressions}\n` +
        `Total Conversions: ${totalConversions}\n` +
        `Total Conversions Value: ${totalConversionsValue}\n\n` + message;
    MailApp.sendEmail(EMAIL, subject, message);
}

function fetchCampaigns() {
    const campaigns = [];
    const selector = AdsApp.performanceMaxCampaigns()
        .withCondition("LabelNames CONTAINS_ANY ['" + CAMPAIGN_LABEL + "']")
        .withCondition("Status = ENABLED")
        .forDateRange("TODAY");

    const iterator = selector.get();

    while (iterator.hasNext()) {
        const campaign = iterator.next();
        campaigns.push({
            id: campaign.getId(),
            name: campaign.getName()
        });
    }

    return campaigns;
}
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