Creative Lens turns the weekly creative review into a Sheet you can act on. It compares every ad’s performance with the previous period, reads the performance labels of responsive search ad assets, flags disapprovals, poor ad strength, pinned-but-LOW assets and spend without conversions, and ranks all of it into a fix list for the week.

How it works

Two windows are queried: the current days and the days before it. Current-period ads are read from ad_group_ad (REMOVED ads excluded), and previous-period totals include paused ads and ads that stopped serving, so week-over-week deltas are honest. RSA assets come from ad_group_ad_asset_view with their performance label, pinned position and enabled flag; if the runtime cannot select asset-level conversion metrics the script falls back automatically and logs it. Landing-page economics group ads by final URL. The fix list is ranked: disapproved ads, spend without conversions, POOR ad strength, LOW assets to replace, CTR drops, pinned-but-LOW assets.

What it writes to the Sheet

  • Summary — KPIs for both periods, ad-strength and asset-label distributions, health counters (disapproved, limited, POOR/AVERAGE ads, LOW assets, pinned assets), top headlines by CTR and the fix list.
  • Ads — one row per ad with current and previous metrics and WoW deltas, type, status, ad strength, approval and final URL.
  • Assets — one row per RSA asset: field, text, performance label, pinned, enabled and metrics.
  • Headlines — aggregated headline texts: ads using it, dominant label, times pinned.
  • Final URLs — landing-page economics per final URL.
  • _history — one persistent row per period for trend charts.

Setup

  1. Create a new, empty Google Sheet with the Google account you will authorise the script with and copy its URL. Do not reuse a Sheet from another script — each Sheet is bound to one script and one Google Ads account.
  2. In Google Ads open Tools → Scripts, create a new script, paste the whole code and give it a name.
  3. Set CONFIG.spreadsheet_url to the Sheet URL. If you run the script from a manager (MCC) account, also set CONFIG.account_id to the client account ID (e.g. 123-456-7890); without it the script stops with a clear error.
  4. Optional: fill CONFIG.email (comma-separated recipients) and/or CONFIG.slack_webhook. Keep the webhook in the code only — it is never written to the Sheet.
  5. Authorise the script, run Preview once to check the log, then Run. The first run creates the tabs, the header rows and the _settings tab.
  6. Schedule it: weekly, Monday at 04:00 account time or later.
  7. Optional: download the Excel dashboard (button above), open its Read me tab and paste the Sheet tabs as described — the column layout matches the script output one-to-one.

Parameters

ParameterDescriptionDefault
spreadsheet_urlURL of the empty Google Sheet the script writes to.'YOUR_SPREADSHEET_URL'
emailComma-separated recipients; blank = no e-mail. Can be overridden in _settings.''
slack_webhookSlack incoming-webhook URL; blank = no Slack message. Lives only in the code.''
account_idClient account ID; required only when running from a manager (MCC) account.''
daysLength of the analysis window in days.7
campaign_filterSubstring filter on campaign name.''
channel_typesRestrict to channel types, e.g. [‘SEARCH’]; empty = all.[]
min_impressions_for_rankingMinimum impressions for an ad or headline to enter rankings.200
min_clicks_no_convClicks without a conversion before an ad is flagged as “spend, no conversions”.30
cost_no_conv_thresholdOptional cost floor for the same flag (0 = clicks only).0
fix_list_sizeMaximum items in the fix list.10
max_rows_writtenRow cap per table; when exceeded a truncation note is added.20000
All values live in the CONFIG block at the top of the script; keys that also exist in the _settings tab can be changed there.

The _settings tab

On the first run the script creates a _settings tab (Key / Value / Notes). Values there override the matching CONFIG entries, so day-to-day tuning happens in the Sheet without editing code. Numbers must be written without thousands separators and with at most two decimals (0.5 or 0,5). The rows script and account mark the Sheet’s owner: if another script or another account opens the same Sheet, it stops before writing anything. Internal tabs starting with an underscore (_settings, _history, _snapshot, _state, _baseline) are language-independent, so switching between the EN/TR/DE builds keeps the stored state.

Notifications

An e-mail and/or Slack digest is sent when at least one channel is configured: period KPIs with deltas, the health line (disapproved · POOR/AVERAGE · LOW assets) and the fix list with a link to the Sheet.

Notes and limits

  • Assets that are no longer in the current version of an ad (enabled = false) stay in the tables but are excluded from the fix list and top headlines.
  • Ad strength and asset labels are Google’s own ratings; the script reports them, it does not recompute them.
  • Every report tab carries a small attribution cell (H1:K1, warning-only protection) and the code header keeps a copyright line; both may be removed by anyone who edits the source.