Google Ads Script: PMax Search Terms Alert

The Google Ads PMax Search Terms Alert script allows you to analyse Performance Max campaigns focused on specific search terms, such as keywords related to your brand or competition.

When this script identifies a campaign that is showing PMax ads for a given keyword, it sends an email. This message contains all currently available metrics related to the phrases searched for this campaign type, including the number of clicks, impressions, conversions, and the value of these conversions.

The tool drives optimization actions: one approach is to add brand names as excluded keywords, or to create multiple PMax campaigns (with or without different excluded keywords) and further analyse the results for each of these configurations.

This Google Ads script utilizes the latest API version (08.2023) and the data available in the „Search Term Categories” section within the Performance Max campaign in online interface.

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: once daily.

/*

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

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *