Introduction to Google Ads Scripts
Using Google Ads scripts is essential to anyone looking to automate any of the more repetitive parts of account management.
Here at Brainlabs, we can’t get enough of scripts. We use them all the time, from something as simple as sending an hourly spend email to much more complex bid management systems that work across multiple accounts. They can be used to adjust ads and bids based on the weather, exchange rates, live betting odds, social media activity, and more! You can see some examples of cool stuff we’ve built on our open-source Google Ads scripts directory. And if you want to use some of our technology that’s arrived back from the future then sign up for one of our paid plans on the Brainlabs Tech Stack.
In this article we’ll cover the following:
- Why you need to start using Google Ads scripts today!
- Some things you can do with scripts
- How to get started
- Additional resources to help you get started
Why you need to start using Google Ads Scripts today!
PPC is complicated. There are dozens of interrelated on- and off-site metrics. There are hidden factors like quality score and competitor activity. There are unquantifiable, fuzzy influences like user intent and ad quality. And everything varies by time, device, demographic, and location.
On top of that, anything can be altered over time: Not only do features come and go, but trends turn and competitors change. Even if you could set up your campaigns perfectly, you can’t leave them alone and expect to keep raking in the highest possible profits.
PPC technology is almost synonymous with third-party bid management tools. The problem with these tools is that they weren’t designed just for you. You can tweak settings but you don’t have full control. Every business has its own needs and goals, so it’s unlikely they can always do precisely what you require. Rather than struggle to manipulate a third-party tool, why not just build something that works for you?
So, what can you do with scripts?
Control over your bids at scale
It may seem obvious that everyone is trying to optimize their campaigns as much as possible, but it matters whether you’re trying to maximise revenue, profit, the number of conversions, or the ROI.
For example, you might not want to be as aggressive as possible; you might want to buy the right number of leads according to the number of operators in your call center.
And your strategy depends on whether you have a fixed budget to use, or if you can spend as much as you want while the results are good.
Only coding gives you the control to do precisely what you want, as many times as you want, as often as you want.
With your own bidding algorithm, you can keep track of your changes, analyze what works, and learn more for the future, rather than just allowing a third-party algorithm to make decisions without all the insider business knowledge that you possess.
Scripts can bring in extra data
PPC depends on many factors, not all of which are standard Google Ads metrics.
You can use scripts to pull Salesforce or Zoho data into Google Ads. Code can make your ads and bids change according to the weather or the sports results.
It can pause ad groups for out-of-stock products, or even bid in real time based on hotel pricing and availability.
Scripts take care of repetition
Reporting can be a hassle — it involves a lot of data manipulation — and it takes time away from optimizing your Google Ads accounts.
You can automatically run reports in Google Ads or Analytics, but if you code your own reports you can customize any external or calculated fields you want and use that data to make custom dashboards.
You can also reduce repetition by using code where you want to make identical changes to similar campaigns — like if you have copies of campaigns with different location settings — or (using the API) automatically sync campaigns in Bing Ads when there are changes made in Google Ads.
Scripts overcome limitations
If you use Google Ads’s native ad scheduling, you can only schedule six bid changes a day. With code you can change bids every hour.
If you set up your campaigns normally, an exact match keyword will pick up any ‘closely matching’ search terms. With code, you can exclude everything but the search term you want.
There are limits to what you can overcome, but those limits are much wider than the limits of just using the Google Ads interface and/or a third-party tool that has to wait for the API to update before they can make changes.
Scripting can handle statistics
If you use Google Ads Campaign Experiments, you can see the difference made by changes to bids, keywords, ads, or placements, but you can’t test any campaign settings.
With an Google Ads script you can build your own experiments, testing anything, with control and test campaigns that switch on and off with alternate ad schedules.
Then you can code a test to see if those results are statistically significant.
Coding does the worrying for you
A program can watch your accounts all day, every day, so you don’t have to. You can set up emails so you’re warned when URLs break, performance plummets, or budgets are in danger of being exhausted too soon.
How do I get started with Google Ads scripts?
You can find the scripts page in the Bulk Operations tab hiding in the sidebar. Click on Create and manage scripts and then +Script button to begin. You will be taken to a page containing a box, a space for writing and executing your code. These scripts will act upon the account in which they are located. You can write scripts which will act on multiple accounts, which you can find in the Bulk Operations tab when viewing your MCC.
Clicking on API Documentation takes you to the reference pages for Google Ads scripting. Becoming proficient at scripting means understanding and becoming adept at using the reference documentation. This is covered in greater detail in a later section. In addition to this, there are numerous examples of common tasks which you can adapt to your specific needs under Show examples.
If you’re new to JS or have never programmed before, make sure you understand the basics. There are many great online resources to learn from, including Codecademy.
As a refresher:
- Variable: A variable contains information which can be accessed at a later point in time.
- String: A string is information in the form of text wrapped in quotation marks. It is one of the types of data that can be stored in a variable; the other type is numbers.
- Function: A function contains code between two curly brackets which can be executed over and over again by writing out the function’s name – known as calling the function.
- Parameter: A parameter is information in the form of a variable which is needed by a function. A function can have any number of parameters, including none at all.
- Object: An object is a collection of variables and functions contained between two curly brackets. The object pointed to in the picture, MailApp, is one of the many objects that comes ready-made in Google Ads.
- Method: When a function is contained within an object, it is known as a method. From the picture: the sendMail method is one of the functions belonging to the MailApp object.
You will inevitably come to rely quite heavily on the documentation provided so here is a simple worked example to show how simple it is to use.
The following snippet shows how to retrieve a campaign from Google Ads:
- We define a campaignSelector on lines 2–3 using AdWordsApp.campaigns(). There are many options available to the campaignSelector, known as methods.
- To make sure we’re looking at just one campaign, we use the withLimit() method which specifies the number of campaigns to use in the brackets (known as the argument).
- If you don’t include withLimit, the selector will try to pull all the campaigns stopping at a maximum of 50,000.
- You can see a list of possible methods here. Clicking on the name of a method in the documentation will scroll you down to that section, Wikipedia-style.
- One of the most commonly used options is the withCondition() method where you can refine your search by choosing campaigns with certain names or those which have spent more than a threshold amount, for example.
If you have multiple withCondition methods, the selected campaigns will satisfy all the conditions (think of it as a filter with conditions joined by an AND operator, e.g. cost >10 AND cost < 30).
For example, how would you be able to choose two campaigns that have completely unrelated names? Take a look at the first code snippet below. We included two withCondition lines in our selector.
As a result all the campaigns pulled by the selector will have to satisfy both conditions — not very useful when trying to return data on unrelated campaign groups.
You’ll notice that using multiple conditions can be quite restrictive because you can’t specify campaigns which satisfy one of two conditions. The documentation won’t help you here but we found a solution.
As in the second code snippet, use an array containing a list of all the campaign names you want your selector to pull. This technique overcomes the problem in the first snippet as campaigns with either name are now retrieved by the selector.
Going through the campaign –> keyword hierarchy is time consuming and using a keyword selector with a campaign name condition such as the one shown in the second snippet is much more efficient.
Code snippet 1:
Code snippet 2:
Example 1: Hourly spend email
This worked example will calculate the cost of your campaigns over the last hour and automate an email with the details.
Here’s a basic road map of the script:
- We pull a list of campaigns from Google Ads.
- We go through the list of campaigns one by one and get cost data on each.
- The results are emailed to a few lucky recipients.
The code is below. Don’t worry if any of it is unfamiliar, we’ll comb through it line-by-line.
- Line 1: As with all Google Ads scripts this one contains a function called main. The code inside the curly brackets of the main function is executed when your script is run.
- Lines 3–4: We’re declaring these variables so we can use them later. The variable emailContent will contain the data to be emailed: the campaigns and how much they cost. The variable total will house the total cost.
- Lines 6–8: The first step is to create a selector. Selectors and iterators (you’ll meet iterators in a moment) are the bread and butter of Google Ads scripting.
In basic terms, a selector is a list of Google Ads objects — in our case campaigns — with which you interact. All the changes you make and data you pull will be done through a selector.
- The methods on lines 7 and 8 provide the conditions on which campaigns are pulled from Google Ads. We’ve chosen to go for campaigns which have cost more than £10 (line 7) in the last week (line 8).
- By not including any methods after campaigns(), you will return all the campaigns in your account.
- Line 10: Now it’s time to create an iterator. The iterator allows you go through each campaign, pulling data or making changes as you go along (for example, you might want to change budgets). This process is known as iterating through the campaigns.
- Line 11: Let’s iterate through. Use a while loop together with the hasNext() method to do this, as in the script image. You can think of the iterator and while loop as looping through an array of campaigns.
- Line 12: The method next() picks out the next campaign in the iterator. You can now interact with the current campaign by pulling data or making changes.
- Line 13: We want to match a campaign name to its cost. To retrieve the campaign name, use the code set out in line 13. This is the getName() method.
- Line 14: To retrieve performance statistics for the campaigns, first specify a date range. This is the job of the getStatsFor() method. We use this method on our campaign with parameter LAST_WEEK to let Google Ads know that we want last week’s data.
- Line 15: Using the stats object, we can retrieve any of last week’s performance data for our campaigns. We’ve chosen the getCost() method, which returns the cost. Be sure to check out the link for the stats documentation page at the bottom of the article to see all the other types of data you can pull from Google Ads.
- Line 16: Once we have the data we need (the cost and name of our campaign) we can format the data in a string ready to be emailed. The \n character starts a new line so that each campaign sits neatly on its own row.
- Line 17: This line gives us the total cost of all the campaigns.
- Lines 20–24: Now send the email containing the cost of your campaigns!
Example 2: Scanning landing pages
Landing pages with broken URLs can wreak havoc in your Google Ads account. Whether the links have moved or were inputted incorrectly from the start, the outcome is the same: you’re paying for dead-end clicks.
As before, here is a basic road map of the script:
- Grab all the keywords from your account and gets their associated destination URLs
- Check the response code of these URLs
- Any that do not receive a whitelisted response (200, 301, 302) will be emailed to relevant parties.
Below is the code, followed by a line-by-line explanation of what it does:
- Line 1: We start as usual with function main().
- Line 3: This array contains the values of whitelisted URL response codes. A code of 200 means everything is working fine. A 301 or 302 code means the page you’re looking for has been moved and any users will be redirected to the correct page.
- Line 4: This is the string containing the recipients of the broken URLs email. To add more addresses, just separate them out using commas inside the quote marks. To have just one email, wrap one email address in quote marks, e.g. “userA@example.com”.
- Lines 7–8: Here we’re creating two arrays to house URLs. The array urls will contain a list of all the unique URLs in the Google Ads account and badUrls will have a list of all the URLs which didn’t return an acceptable response code. These are the URLs which will be emailed out at the end of the script.
- Lines 10–14: Here we construct a keyword iterator. The selector picks keywords with active keywords in active campaigns within enabled ad groups filtered using the withCondition()
Since URLs can be set at the ad level as well as the keyword level, to construct an iterator which will get ads and not keywords, change AdWordsApp.keywords() to AdWordsApp.ads().
- Line 15: The while loop combined with the iterator’s hasNext() method is the standard way to loop through the keywords.
- Line 16: Create a keyword object in the variable keyword.
- Line 17: The getDestinationUrl() method will return the destination URL associated with the keyword.
- Line 18: The if condition is just a check to make sure that the URL actually exists before continuing.
- Line 19: Many people use tracking parameters in their URLs. The tracking parameters can be used for various tasks such as signalling the source of the traffic to your database. The parameters are placed after a URL and separated using a question mark, ?. Tracking parameters are unnecessary when checking if a URL is functioning correctly and can even cause errors, so it’s best practice to remove them here.
The split() method of a string is used to split the string up at the specified parameter and returns the different portions as an array. Choosing the question mark as we do on line 19 splits the string into an array with two elements. Element zero contains the URL so we specify it by writing .
- Lines 20-21: This if condition is here to make sure we have a list of unique URLs in the account. For larger accounts it can take a lot of time to check over all the URLs. By making sure you are only checking each URL once your scripts will run much more quickly.
Here’s what’s happening in plain English: The if condition asks if the current URL in url is contained within the array urls. If the URL is absent (indexOf returns -1) then the if condition is satisfied and the URL is pushed to the array on the next line.
If, however, the URL was already contained in the array, then the code will skip the if condition.
- Line 26: Set up the URL checking options.
- Line 29–41: We start a for loop to go through all the unique URLs that we put into the urls array. We’ll check the urls one by one.
- Line 30: Here we’re introducing something new: the try-catch. If the code executed in the try block has an error, rather than bringing the script to a halt, the script jumps to the catch and executes the code contained there instead. This part of the script is useful for containing errors and not letting them stop your scripts mid way.
- Line 31: Google Ads has a collection of tools which you can find as the methods belonging to the Utilities object. One of these methods lets you fetch a web page. Within this for loop we’re fetching all our URLs and putting the results in the response
- Line 32: Once fetched we can get data from our web page. The getResponseCode() method will give us the response code we’re after to evaluate the status of the page. We stick the response code in our code
- Lines 37–40: We check code is acceptable by comparing it to the array of valid codes defined at the top of the script. If not we’ll put the URL in the badUrls
- Lines 43+: After an initial check to make sure badUrls isn’t empty (to make sure that broken URLs have actually been found), an email is sent containing the details in the body of the message and in an attachment.
Example 3: Tracking account-level quality score
Google does not provide an account-level quality score, only at the keyword level. It is tedious and time-consuming to go through the quality score of each keyword so it’s scripts to the rescue! Here is an example inspired by this piece by Fred Vallaeys on Search Engine Land.
Here is our basic road map:
- Get all the keywords in our account, and their associated quality score and number of impressions
- Aggregate each keyword’s contribution to the account level quality score
- Output this information to a Google Sheet to see how it changes over time
Here is the code followed by a line-by-line explanation:
- Line 1: As before, our function is called main().
- Lines 3–4: We start off with totalImpressionsAnalysed and totalQualityScoreAnalysed as zero, each keyword we analyse will add its own metrics to these totals.
- Lines 6–7: We begin our keywordIterator with all active keywords.
- Line 8: We filter to include only campaigns containing a specific substring (case insensitive).
- Lines 9–10: We only look at enabled campaigns and adgroups.
- Lines 11–13: We order by impressions and limit our query to 10,000 due to Google Ads’s built-in time limit. The script cannot run for more than 30 minutes and we want to ensure that we get a result in that time. Should we have more than 10,000 keywords in our account, we know we are at least looking at the 10,000 with the most impressions and therefore with the most effect on account-level quality score.
- Line 16–18: Loop through our keywords and set the variable keyword to the keyword we are currently analysing.
- Lines 19–21: Grabs the quality score and number of impressions for the keyword and assigns them to variables qualityScore and impressions.
- Line 22: Calculate the quality score contribution of the keyword by multiplying quality score by number of impressions.
- Lines 24–25: Add this quality score contribution and the total number of impressions analysed to the running totals which we initialised on lines 3 and 4.
- Line 28: Having gone through all the keywords, we can now calculate the total account quality score by dividing the totalQualityScoreAnalysed by the totalImpressionsAnalysed.
- Line 33: Insert the URL of the Google Sheet where you would like to record your quality score
- Line 34: Like AdWordsApp and MailApp, SpreadsheetApp is the script’s way of communicating with Google sheets. Here the methods applied open the spreadsheet at the URL provided in line 33, and point at the active sheet within that spreadsheet.
- Line 35: We add a new row to the spreadsheet consisting of two columns, today’s date, and the total account quality score.
You can set this script to run every day in Bulk Operations -> Create and manage scripts -> + Create Schedule and each time it runs a new row will be appended to your spreadsheet.
Of course there is also the Google Ads API, but getting started with scripts is much quicker and a lot less daunting, with only a few simple steps before you’re ready to go.
- Search Engine Land has plenty of articles and example scripts to maximise using Google Ads scripts
- The Google Ads documentation has some ready made examples for some common tasks in Google Ads Scripts as well as some fully fledged, advanced solutions.
- We publish some of the newer scripts we produce on the Brainlabs blog.
- Koozai’s list of 100 scripts
- RankHammer’s AdWords Scripts Compilation
People to Follow
Steve Hammer of RankHammer