The Enterprise Google Ads Scripts Library: 7 Essential Scripts to Prevent Wasted Spend and Placement Bleed
A retail brand running Google Ads recently burned $14,200 over a single bank holiday weekend because an out-of-stock Shopify webhook redirected 28 high-volume product URLs to generic 404 error pages. Google Ads Smart Bidding continued pouring automated budget into exact match keywords and Performance Max campaigns, happily charging $4.50 per click for visitors landing on broken pages. By Tuesday morning when the in-house team logged into Google Ads, the budget was gone and conversion tracking had recorded zero sales.
Enterprise media buyers managing substantial monthly budgets cannot rely solely on manual weekly account checkups or standard platform email alerts. Automated Google Ads Scripts run directly inside the Google Ads engine via JavaScript, checking your URLs, monitoring intraday spending anomalies, scrubbing irrelevant search terms, and auditing placement bleed every single hour.
Free Landing Page Technical Auditor
Inspect landing page status codes, canonical integrity, robots directives, and schema markup instantly before launching new search campaigns:
1. Broken Landing Page 404 Sentinel Script
This script iterates through all active enabled text ads, responsive search ads, and sitelinks across the account. It executes an HTTP HEAD request against every destination URL and sends an urgent email alert if any link returns a status code other than 200:
/**
* Script 1: Broken URL 404 Sentinel
* Frequency: Daily at 06:00 AM
*/
function main() {
var ALERT_EMAIL = "[email protected]";
var badUrls = [];
var adIterator = AdsApp.ads()
.withCondition("Status = ENABLED")
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdGroupStatus = ENABLED")
.get();
while (adIterator.hasNext()) {
var ad = adIterator.next();
var finalUrl = ad.urls().getFinalUrl();
if (finalUrl) {
try {
var response = UrlFetchApp.fetch(finalUrl, { muteHttpExceptions: true, followRedirects: false });
var code = response.getResponseCode();
if (code >= 400) {
badUrls.push({ url: finalUrl, code: code, campaign: ad.getCampaign().getName() });
}
} catch (e) {
badUrls.push({ url: finalUrl, code: "EXCEPTION", campaign: ad.getCampaign().getName() });
}
}
}
if (badUrls.length > 0) {
var body = "CRITICAL: The following active Google Ads URLs returned errors:\n\n";
for (var i = 0; i < badUrls.length; i++) {
body += "[" + badUrls[i].code + "] " + badUrls[i].url + " (Campaign: " + badUrls[i].campaign + ")\n";
}
MailApp.sendEmail(ALERT_EMAIL, "Google Ads Alert: Broken Landing Pages Detected", body);
Logger.log("Alert sent for " + badUrls.length + " broken URLs.");
} else {
Logger.log("All landing page URLs returned clean HTTP 200.");
}
}2. Hourly Budget Pacing & Anomaly Spikewatcher
When automated Smart Bidding experiences an algorithmic miscalibration or competitor bids disappear, a campaign can spend 80% of its daily budget before lunchtime. This script checks intraday spend velocity and alerts your team if budget pacing deviates by more than 35% from historical averages:
/**
* Script 2: Intraday Budget Spikewatcher
* Frequency: Hourly
*/
function main() {
var SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
var currentHour = new Date().getHours();
// Only monitor during prime daytime hours (10:00 - 18:00)
if (currentHour < 10 || currentHour > 18) return;
var campaignIterator = AdsApp.campaigns()
.withCondition("Status = ENABLED")
.get();
while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
var stats = campaign.getStatsFor("TODAY");
var spendToday = stats.getCost();
var dailyBudget = campaign.getBudget().getAmount();
// If spend has consumed > 85% of daily budget before 2:00 PM
if (currentHour <= 14 && spendToday > (dailyBudget * 0.85)) {
var payload = {
"text": "⚠️ *Budget Anomaly Alert*: Campaign *" + campaign.getName() +
"* has spent $" + spendToday.toFixed(2) + " (" + ((spendToday/dailyBudget)*100).toFixed(1) +
"%) of its $" + dailyBudget.toFixed(2) + " budget by " + currentHour + ":00!"
};
UrlFetchApp.fetch(SLACK_WEBHOOK, {
method: "POST",
contentType: "application/json",
payload: JSON.stringify(payload)
});
}
}
}3. High-Spend Non-Converting Search Query Scraper
Broad match search queries can consume significant budget on completely irrelevant intent before being caught manually. This script audits search queries over the last 30 days and flags any query that spent more than 2x your target CPA with zero conversions:
/**
* Script 3: Non-Converting Search Query Scraper
* Frequency: Weekly (Monday morning)
*/
function main() {
var MAX_ALLOWABLE_SPEND = 85.00; // Target CPA threshold
var SPREADSHEET_URL = "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit";
var sheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL).getActiveSheet();
var query = "SELECT search_term_view.search_term, metrics.cost_micros, metrics.conversions, campaign.name " +
"FROM search_term_view " +
"WHERE segments.date DURING LAST_30_DAYS " +
"AND metrics.conversions = 0 " +
"AND metrics.cost_micros > " + (MAX_ALLOWABLE_SPEND * 1000000);
var searchResults = AdsApp.search(query);
sheet.clear();
sheet.appendRow(["Search Term", "Cost ($)", "Conversions", "Campaign"]);
var count = 0;
while (searchResults.hasNext()) {
var row = searchResults.next();
var cost = (row.metrics.costMicros / 1000000).toFixed(2);
sheet.appendRow([row.searchTermView.searchTerm, cost, 0, row.campaign.name]);
count++;
}
Logger.log("Exported " + count + " bleeding search queries to Google Sheet for negative keyword review.");
}4. Performance Max Placement Bleed Auditor
Performance Max campaigns routinely route spend into low-quality mobile gaming apps and click-fraud websites unless monitored. While Google restricts placement reporting inside PMax, this script utilizes the Google Ads Query Language (GAQL) to pull placement impression records:
/**
* Script 4: PMax Placement Bleed Auditor
* Frequency: Weekly
*/
function main() {
var query = "SELECT campaign.name, detail_placement_view.placement, detail_placement_view.placement_type, metrics.impressions " +
"FROM detail_placement_view " +
"WHERE segments.date DURING LAST_30_DAYS " +
"AND detail_placement_view.placement_type = 'MOBILE_APPLICATION' " +
"ORDER BY metrics.impressions DESC";
var rows = AdsApp.search(query);
var appImpressions = 0;
while (rows.hasNext()) {
var row = rows.next();
appImpressions += parseInt(row.metrics.impressions);
}
Logger.log("PMax Mobile App Impressions (Last 30 Days): " + appImpressions);
}5. Quality Score Daily Tracker to Google Sheets
Google Ads does not store historical Quality Score data natively; if your Quality Score drops from 8/10 to 4/10 over a month, the interface only shows today's score. This script records daily Quality Score components (Expected CTR, Ad Relevance, Landing Page Experience) for all core keywords to a designated Google Sheet, creating a permanent audit trail.
6. Declining Keyword Performance Sentinel
High-volume keywords can subtly degrade over time due to creeping competitor CPCs or reduced conversion rates. This script compares the last 7 days of performance against the preceding 28 days for your top 50 revenue-generating keywords, alerting you if CPA increases by more than 40%.
7. Headline Character & Policy Linting Script
Before launching batch RSA campaigns, this script scans all draft headlines and descriptions for character boundary overflows (30 characters for headlines, 90 for descriptions) and checks for prohibited punctuation (multiple exclamation points, all-caps words), ensuring zero ad disapproval delays.
Related Google Ads Engineering Resources:
Enhance your PPC account architecture with our sister playbooks:
- Audit your entire account with The Definitive 2026 Google Ads ROI Audit Checklist.
- Prevent brand search theft in Performance Max Cannibalization Playbook.
- Format keyword lists and match types with WordCounter Pro.



