It’s a bad idea to have the same search query leading to different ad groups. Your data on that query won’t be in one place, it’ll be harder to see how it performs, and it gets in the way of managing bids (turning bids down in one group means they could pop up in a different group with a higher bid, i.e. still wasting money).
And it messes with your relevance. Even if you have a beautifully targeted message and landing page for a keyword like [sterilized standardized scientificized owl], you can end up with the specific queries going to a keyword like +owl with a more generic ad. And it’s no mean feat to manually spot this happening!
This script finds out when the same query is appearing within different ad groups. It saves a report to a Google Sheet, showing the queries from the last 30 days and the ad groups they appear in. It also shows metrics like Impressions and Cost, so you can see where they perform the best.
With this script, you can just drop negative keywords into the ad groups that you don’t want the query leading to, saving you time and optimizing your Google Ads account.
A typical output will look like this:
How do I use it?
First, make a blank Google Sheet for the report.
Then head over to Google Ads to set up a new script. After copying in the code below, you’ll need to make a few choices in the options:
Set spreadsheetUrl to the URL of the sheet you’ve just made.
If you want to ignore low-traffic queries, set impressionThreshold to a number. The script will only look at queries with more impressions than this threshold.
Set to 0 to look at all available queries.
Filter the campaigns to check with the two arrays, campaignNameContains and campaignNameDoesNotContain. For example, if campaignNameContains is [“Brand”, “Generic”], then only campaigns with names containing “brand” or “generic” are included. If campaignNameDoesNotContain is [“Shopping”], then any campaigns with names containing “shopping” are ignored.
This is not case-sensitive.
Leave blank, , to not exclude any campaigns.
If you need to put a double quote into campaignNameContains or campaignNameDoesNotContain, put a backslash before it.
If ignorePausedCampaigns is true, then the script will only look at currently active campaigns. Set this to false if you want to also check in currently paused campaigns.
The script will always use the first sheet of the spreadsheet for the report, so if you want to run it multiple times, then move the data so it isn’t overwritten.
If the script keeps timing out, you could run it multiple times using campaignNameContains and campaignNameDoesNotContain to look at different campaigns on each run.
If you have copies of campaigns for different locations, use campaignNameContains to look only at one location at a time. For example, run the script once with campaignNameContains set to [“-USA”] to look at American campaigns, and then run again with campaignNameContains set to [“-UK”] to look at the British versions.