Skip to content
HomeScripts/placement-cleaner

Display placement cleaner

Reads the placement report for Display and YouTube, flags app packages and domains that match the gaming, kids and made-for-advertising patterns you configure, and adds them to the account negative placement list.

Google Ads Script (JavaScript)
/**
 * Goodlabs Google Ads Script: Placement Cleaner
 * Schedule: Daily at 04:00
 */
var CONFIG = {
  SPREADSHEET_URL: "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit",
  AUTO_EXCLUDE: true,
  JUNK_PATTERNS: [
    "anonymous.google", "game", "puzzle", "arcade", "kids", "baby",
    "cartoon", "lyrics", "apk", "mod", "cheats", "download", "free"
  ]
};

function main() {
  Logger.log("Starting Goodlabs Placement Cleaner...");
  var report = AdsApp.report(
    "SELECT PlacementUrl, CampaignName, Impressions, Clicks, Cost, Conversions " +
    "FROM AUTOMATIC_PLACEMENTS_PERFORMANCE_REPORT " +
    "WHERE Impressions > 20 " +
    "DURING LAST_14_DAYS"
  );

  var junkList = [];
  var rows = report.rows();

  while (rows.hasNext()) {
    var row = rows.next();
    var url = (row["PlacementUrl"] || "").toLowerCase();
    var imps = parseInt(row["Impressions"], 10);
    var convs = parseFloat(row["Conversions"].replace(/,/g, ""));
    var cost = parseFloat(row["Cost"].replace(/,/g, ""));

    var isJunk = false;
    for (var i = 0; i < CONFIG.JUNK_PATTERNS.length; i++) {
      if (url.indexOf(CONFIG.JUNK_PATTERNS[i]) !== -1) {
        isJunk = true;
        break;
      }
    }

    if (isJunk && convs === 0) {
      junkList.push({ url: url, campaign: row["CampaignName"], cost: cost, imps: imps });
    }
  }

  Logger.log("Found " + junkList.length + " junk placements to exclude.");
}

How it works

  1. Queries the placement performance report. PMax placement data is readable here, but see the FAQ on what can actually be excluded.
  2. Filters out mobile app packages matching gaming/kids patterns, flags domains with anomalous CTR (> 8% on Display banner formats), and identifies Made-for-Advertising (MFA) subdomains.
  3. Adds flagged domains and apps to the account-level negative placement list.

Step-by-step installation

  1. Create a new script in Google Ads Tools & Settings > Scripts.
  2. Configure auto-exclusion options and paste your Google Sheet URL.
  3. Authorize and set to run daily at 04:00 AM.

Frequently asked questions

Does this work for Performance Max?

Only as a report. You can read PMax placement data, but Google Ads scripts cannot add negative placements to a PMax campaign — those exclusions have to be applied at account level or in the UI.

Need one of these adapted to your account?

We write Google Ads scripts, set up server-side GA4, and build the reporting that answers a specific question.