Freebies 11 min read

Free Google Ads Scripts: PMax Asset Group Exporter + Search Term Intent Classifier

Two production-grade Google Ads Scripts solving 2026's biggest PPC pain points — Performance Max asset-group visibility and broad-match-with-Smart-Bidding waste. Read-only by default, MCC + single-account flavors, MIT-licensed.

A
Ann McBride
·

If you’re managing Google Ads in 2026 you’re dealing with two structural problems Google made worse this year:

  1. Performance Max gives you no asset-group-level reporting in the UI. Campaign totals, asset stats — fine. But the layer in the middle that actually drives performance? Black box.
  2. Broad match + Smart Bidding is the new default. Your “exact match” keyword now matches anything Google decides is “similar intent,” and the only real lever you have left is negative keywords.

Both have paid SaaS tools built around them — Optmyzr, Negator.io, Adriel, Adalysis — billing $30 to $200+ per month for what’s basically a wrapper around the Google Ads API.

We just open-sourced both. MIT-licensed, no signup, no upsell.

Repo: github.com/aumlytics/google-ads-scripts

What’s in v1

ScriptWhat it doesFlavors
pmax-asset-group-exporterPer-asset-group spend, conversions, ROAS, CPA, CTR for every Performance Max campaign → Google Sheet + email digestsingle-account + MCC
search-term-intent-classifierClassifies every search term by intent, flags + (optionally) auto-applies negative-keyword candidatessingle-account + MCC

Both are read-only by default. The intent classifier has a DRY_RUN flag — flip it only when you’ve reviewed the output for at least one cycle.

Script 1: PMax Asset Group Performance Exporter

The problem: Performance Max is supposed to be your “set it and forget it” Smart Bidding play. The UI shows you campaign-level totals and individual asset stats (Headline 3 has 47% engagement!) — but not the layer in between. The asset group is where audience signals, creative themes, and landing pages bundle together. Google decides which group gets impressions; you can only watch.

Most agencies build this missing report in Looker Studio with Supermetrics ($199+/mo) or pipe Google Ads → BigQuery → custom dashboard. Both work; both are overkill if you just want to know “which of my 6 asset groups is actually performing.”

What the script does:

  • Walks AdsApp.performanceMaxCampaigns(), then .assetGroups() per campaign
  • Pulls impressions, clicks, cost, conversions, conversion_value for each asset group
  • Derives CTR, CPC, CPA, ROAS with guarded division (blank cells when denominator = 0; no Infinity, no fake zeros)
  • Appends a timestamped row per asset group to a Google Sheet
  • Sends an HTML email digest covering account totals (with delta vs prior period), top-spend asset groups, best/worst ROAS (gated by a minimum spend so you don’t get noise), and waste alerts for asset groups with zero conversions

Run it daily and you have time-series data you can pivot, chart, or feed into a free Looker Studio dashboard.

MCC flavor: uses executeInParallel to walk every child account (or a labeled subset), merges results into one cross-account Sheet, and emails a single combined digest. Up to 50 child accounts run in parallel; for larger MCCs the ACCOUNT_LABEL filter keeps you under quota.

Currency caveat for MCC users: different child accounts run in different currencies. The Sheet records each account’s currency in column 4 but doesn’t FX-convert. If you sum the Cost column across mixed currencies you’ll get nonsense — filter by currency first.

Script 2: Search Term Intent Classifier + Auto-Negative Suggester

The problem: Google’s match-type “improvements” since 2021 have steadily eroded the precision of exact and phrase match. By 2026, your exact-match keyword marketing analytics platform can serve ads on what is marketing analytics, marketing job description, or analytics careers london. None of those are buyers. All of them eat your budget.

Manually reviewing the Search Terms report every week is the standard advice. It’s also tedious and the obvious patterns are the same every account — “how to”, “what is”, “login”, “support”. The script encodes those patterns and lets you act in bulk.

The classification:

A search term gets the first intent it matches, in priority order:

  1. Brand — contains your brand variants. Never flagged as a negative, even if it never converts directly.
  2. Competitor — contains a competitor name. Not flagged by default (most B2B accounts WANT competitor traffic; B2C may not).
  3. Navigational — contains “login”, “support”, “contact”, “phone number”. Users looking for help, not to buy.
  4. Informational — contains “how to”, “what is”, “tutorial”, “guide”, “vs”. Top-funnel research that rarely converts on first click.
  5. Transactional — contains “buy”, “price”, “near me”, “for sale”. Never flagged — these are gold.
  6. Unclear — no pattern matched. Default for everything ambiguous.

The suggestion rules:

  • informational_no_conv — Informational intent, cost ≥ $25, conversions = 0 → suggest
  • unclear_waste — Unclear intent, cost ≥ $50, conversions = 0 → suggest
  • navigational_any — Navigational intent, clicks ≥ 3 → suggest
  • competitor_block — Competitor intent + setting enabled → suggest (disabled by default)

All thresholds are tunable in the CONFIG block. A $500/day account should run much higher minCost values than a $30/day account.

Two safety levels:

  • DRY RUN (default) — pulls terms, classifies, writes to Sheet, emails digest. Nothing is added to your campaigns.
  • LIVE — same plus adds suggested terms to a shared negative-keyword list (Aumlytics Auto Negatives, configurable). The list is auto-created if missing. You then apply that list to the campaigns you want protected. No campaign-level or ad-group-level negatives are ever created — everything goes through one shared list, so it’s audit-friendly and instantly reversible.

Reverting is one click: un-apply the shared list from your campaigns.

Both scripts are read-only-first by design

Google Ads Scripts can pause campaigns, change budgets, push negatives, do anything the UI can do. That’s powerful and dangerous. Most “free Google Ads scripts” floating around are written for a single account with no thought to MCC quotas, no DRY_RUN gating, and no audit trail.

Our defaults:

  • PMax Exporter: purely read-only. The DRY_RUN flag exists in CONFIG for consistency with the rest of the repo but is unused — there’s nothing to dry-run because nothing is mutated.
  • Intent Classifier: read-only until you explicitly set DRY_RUN = false. The first run after that flip surfaces every action in the email digest with full reasoning (“Applied [how to install x] — Informational intent, cost ≥ $25, conversions = 0”).
  • Shared negative lists, not campaign-level negatives. Every action is grouped in one place; reverting is one click.

Setup time

  • Read the README — 5 minutes per script
  • Paste, tune CONFIG, authorize — 10 minutes per script per account
  • First run + Sheet/email check — 15 minutes
  • Tuning thresholds after first dry run — 5–10 minutes

For MCC users with 5–10 client accounts: about 90 minutes from clone to scheduled run across all accounts. That’s a one-time investment for daily automated insight.

What’s NOT in v1

We deliberately scoped v1 lean. Coming in v2 (separate sessions):

  • Account-Level Anomaly Detector — hourly CPA/ROAS/spend drift detection with rolling 7-day baselines. Alerts when AI bidding goes off the rails before it costs you a weekend.
  • PMax asset-level breakdown — drills inside asset groups to individual assets. Separate script because it multiplies row count 10–30x.
  • Per-account brand/competitor lists in MCC mode — currently the patterns are shared across all child accounts; v2 will key off account name or label.
  • Phrase/Broad match negative suggestion modes — currently EXACT only (safest).

Get it

Find a bug or have a feature request? Open an issue on the repo. We read them.

#google-ads#pmax#performance-max#google-ads-scripts#apps-script#mcc#negative-keywords#search-terms#free-tools#smart-bidding

Share this article

Want This Implemented Correctly?

Let our team apply these concepts to your specific setup — with QA validation and 30 days of support.