Google Ads Scripts 101

There is one question we are forever asking ourselves here: “Is there an easier way to do this?” Anyone who works in PPC can tell you, the devil is in the details. It’s certainly easy to get bogged down in those tedious, brain-melting tasks. Maybe that’s because it’s the way you’ve always done things, or you’re worried it’ll take longer to figure out the time-saving fix. The easy answer to account efficiency? Google Ads Scripts!

Ugh, scripts? But that sounds scary and I don’t know how to code!  We understand your trepidation. So we created this handy guide for script automation 101. Here’s your agenda, welcome to class!

Chapter 1: Intro to Google Ads Scripts

What are Google Ads Scripts?

Google Ads Scripts are pieces of JavaScript placed into a Google Ads account or at the MCC level.

They allow marketers to programmatically manage and report on Google Ads data allowing for the automation of common procedures, and enabling strategies that wouldn’t be feasible through traditional controls. Google Ads Scripts are customizable and can be scheduled as frequently or infrequently as you would like.

What are the benefits?

Google Ads Scripts will save you time!

  • Automate tedious, monotonous tasks that used to take hours
    • Hate sifting through thousands of rows of data to find out what keywords aren’t helping you reach your goal? Don’t waste your time, Google Ads Scripts to the rescue. Schedule scripts to run as often as hourly or as little as monthly.
  • Make account adjustments away from your computer
    • Need to turn off multiple campaigns Sunday at noon but you’re planning on going to the baseball game? No problem! Set up a script to do this for you.
    • Try this script from Free Google Ads Scripts. It can pause or activate campaigns, keywords, or ads—just pick the date!
  • Spend less time reporting and more time strategizing
    • Spending all your time reporting doesn’t drive direct revenue, strategizing what to do with the data does. Let us guide you to increase workflow efficiency.
    • Brainlabs’ 24 hour bidding schedule for Google Ads might be the script for you!
  • Keep things organized
    • Need to label products at a large scale within your account? Easily set up a script and a set of conditions to do this for you saving you hours of sorting through manually.  
    • This script applies labels to keywords based on your rules.
  • Make changes, big or small
    • Make large scale updates at the account level or get right down in the nitty gritty day to day details.
    • We like this script for our Shopping Campaigns. It creates ad groups and product groups in bulk.
  • Make your ads dynamic
    • Insert live data in your ads, increasing the relevancy of your ad to your searchers.
    • This Script can pull in weather data. If it’s raining in Philadelphia, boom—scripts will make the bid adjustment to help get your umbrella ad in position 1.

However, Google Ads Scripts can’t be used with Google Ads for video or Google Ads Express.

What else should I know?

Scripts are not limited to just Google Google Ads. Apps Scripts can be utilized across many of Google’s services including: Sheets, Docs, Forms, Sites, Drive, Gmail, Calendar, Contacts, Groups, Maps, and Translate. For instance, this script integrates Docs, Sheets, & Calendar to send SMS updates within 5 minutes of a webpage going down. That way if you’re out of the office/away from your desk, you’d get notified immediately if there are pages down on your site.

We could seriously go on and on, but we’ll focus on scripts for Google Ads.

We understand, not many beginners understand the backend coding and how these scripts ultimately work within Google Ads. Check out Chapter Two to start learning the basics of JavaScript and Google Ads Scripts.

Chapter 2: Google Ads Scripts Code for Beginners

PPC Essentials

Congratulations on completing Chapter One! Now you know what scripts are and how they’ll help you, but we do admit, that scripts code still looks pretty scary.

The next three chapters are dedicated to breaking down and explaining all that code. First up, we’ll learn the basics for editing Google Ads scripts in this section. Next, take your lesson a step further with our JavaScript tutorial. If you’re a pro, check out our advanced section for script experts.

Even if you can’t understand JavaScript, making the jump to reading Google Ads Scripts is simply a matter of familiarizing yourself with a few patterns. Scroll down and get started


Google Ads Scripts generally follow this layout:


Any script you find online should begin with comment indicating the license and copyright. For Google Ads scripts, these are virtually always free MIT or Apache licenses, which allow you to change and use the script for any (including commercial) purpose as long as you keep the copyright/license in tact when you use the script and do not try to sell the script itself.

// Copyright 2015, Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.


The license is followed by a comment block with information about the script, including the script author, version, and a description of what it does. Sometimes the description will also include usage instructions, or a link to more detailed documentation.

* @name Ad Performance Report
* @overview The Ad Performance Report generates a Google Spreadsheet that
* contains ad performance stats like Impressions, Cost, Click Through Rate,
* etc. as several distribution charts for an advertiser account. See
* for more details.
* @author AdWords Scripts Team []
* @version 1.0
* @changelog
* - version 1.0
* - Released initial version.


The first actual code in the script will be a set of variables named all uppercase letters. These are the configuration settings for the script. There may be many or just one.

A comment above each setting describes of how it affects script functionality (and instructions for determining or obtaining the proper value, if it’s not straightforward). If there is no comment for a setting, chances are, it’s not something you should mess with!

Required settings are generally listed first and have placeholder values such as: “INSERT_SPREADSHEET_URL_HERE“. Optional settings are either blank or have default values.


In many cases, the defaults for optional settings are optimal values for the script. Before dramatically changes any of the defaults, you should test smaller changes incrementally, and observe the impact on script functionality and execution speed.

// Comma-separated list of recipients. Comment out to not send any emails.

// URL of the default spreadsheet template. This should be a copy of

The Rest of the Code

Everything that follows is the actual script—the code that does what’s described in the description, according to the configured settings. Note, this code can be very long, but most scripts are designed so you’re not required to touch (or even look at) any of it.

* This script computes an Ad performance report
* and outputs it to a Google spreadsheet.
function main() {
Logger.log('Using template spreadsheet - %s.', SPREADSHEET_URL);
var spreadsheet = copySpreadsheet(SPREADSHEET_URL);
Logger.log('Generated new reporting spreadsheet %s based on the template ' +
'spreadsheet. The reporting data will be populated here.',

var headlineSheet = spreadsheet.getSheetByName('Headline');
headlineSheet.getRange(1, 2, 1, 1).setValue('Date');
headlineSheet.getRange(1, 3, 1, 1).setValue(new Date());
var finalUrlSheet = spreadsheet.getSheetByName('Final Url');
finalUrlSheet.getRange(1, 2, 1, 1).setValue('Date');
finalUrlSheet.getRange(1, 3, 1, 1).setValue(new Date());

outputSegmentation(headlineSheet, 'Headline', function(ad) {
return ad.getHeadline();
outputSegmentation(finalUrlSheet, 'Final Url', function(ad) {
return ad.urls().getFinalUrl();
Logger.log('Ad performance report available at\n' + spreadsheet.getUrl());
'Ad Performance Report is ready',

* Retrieves the spreadsheet identified by the URL.
* @param {string} spreadsheetUrl The URL of the spreadsheet.
* @return {SpreadSheet} The spreadsheet.
function copySpreadsheet(spreadsheetUrl) {
return SpreadsheetApp.openByUrl(spreadsheetUrl).copy(
'Ad Performance Report ' + new Date());

* Generates statistical data for this segment.
* @param {Sheet} sheet Sheet to write to.
* @param {string} segmentName The Name of this segment for the header row.
* @param {function(AdWordsApp.Ad): string} segmentFunc Function that returns
* a string used to segment the results by.
function outputSegmentation(sheet, segmentName, segmentFunc) {
// Output header row.
var rows = [];
var header = [
'Num Ads',
'CTR (%)',

var segmentMap = {};

// Compute data.
var adSelector =
.withCondition('Impressions > 0');
var adIterator = adSelector.get();
while (adIterator.hasNext()) {
var ad =;
var stats = ad.getStatsFor('LAST_WEEK');
var segment = segmentFunc(ad);
if (!segmentMap[segment]) {
segmentMap[segment] = {
numAds: 0,
totalImpressions: 0,
totalClicks: 0,
totalCost: 0.0
var data = segmentMap[segment];
data.totalImpressions += stats.getImpressions();
data.totalClicks += stats.getClicks();
data.totalCost += stats.getCost();

// Write data to our rows.
for (var key in segmentMap) {
if (segmentMap.hasOwnProperty(key)) {
var ctr = 0;
if (segmentMap[key].numAds > 0) {
ctr = (segmentMap[key].totalClicks /
segmentMap[key].totalImpressions) * 100;
var row = [
sheet.getRange(3, 2, rows.length, 6).setValues(rows);

Editing for Basic Customization

Many example scripts will work without much tweaking, but may need to be configured with your own information (i.e. an account id, a Google spreadsheet URL, etc). Configuration settings are the variables named with all-caps, listed after the metadata comment at the top of the script.

The script instructions (either online documentation or in the comments at the top of the script) often indicate which settings you have to update, but it’s a good idea to look at the comment above each variable to make sure none are marked as required.

Even if none are required, you may want to tweak some settings to better suit your needs.

// Comma-separated list of recipients. Comment out to not send any emails.

// URL of the default spreadsheet template. This should be a copy of


Updating Settings

When updating the settings, take care to only change the value. (Note, if the value is surrounded by quotes, those quotes simply delimit the value, and are not part of the value itself.)

Be careful not to:

  • Delete quotes surrounding the value
  • Delete any semicolons or commas
  • Accidentally type any stray characters in the code
  • Change the variable name

This is code, so a single missing or unexpected character can break the script. So it may look like improper use of punctuation, but don’t fix it!



If there is a default or placeholder value, double-click on the value, and only the part that is safe to edit will be selected.


Adding Your Own Comments

Feel free to leave notes for yourself/others by adding a code comment.



Particularly for optional settings, it’s a good idea to leave a comment with the date, your email, and an explanation of why you changed the setting. It might seem unnecessary, but trust us, later you (or someone else) will be really glad you did.

Chapter 3: JavaScript Basics


This intro to JavaScript is for anyone learning JavaScript for any purpose. Although part of a series for Paid Search practitioners, this chapter covers only universally-applicable JavaScript code and concepts. After the first paragraph, this chapter is not specific to Paid Search in any way.


AdWords Scripts are simply JavaScript, imbued with some Google AdWords concepts and libraries.  As Google states, an “entry-level familiarity with JavaScript is needed” to get started, so here is a crash course. If you’re familiar with JavaScript, you can jump ahead to the advanced AdWords Script chapter.

Note: This is a practical introductory guide to JavaScript. Many concepts are simplified, sometimes at the expense of thoroughness and preciseness. If JavaScript was our universe, this guide glosses over the gory quantum details, giving only the simpler laws and abstractions that govern the day-to-day for most mortals.



JavaScript is most well-known as part of the triumvirate of technologies upon which web content is built.  Content is structured using HTML, styled using CSS, and JavaScript … well, does everything else.  The internet would be a far plainer place without JavaScript.  This “client-side JavaScript” lives on webpages and runs right in your browser, but JavaScript can also run on servers to conduct back-end tasks.  AdWords Scripts are an example of the latter.

To be able to understand and edit AdWords scripts, you’ll need to understand its syntax. Syntax is the set of the vocabulary and grammar rules for the language.



Java and JavaScript are commonly confused, but they are completely different languages.



A comment is a section of a script that will be ignored when the script is run.

Comments are primarily used to provide documentation and explanations of what a particular piece of code does in plain English.  Scripts often begin with a comment section, which gives general information about the entire script, such as an overview of what it does, the author, and sometimes URLs for more detailed documentation.

There are line comments, which start with // and continue until the end of the line.


// This is a line comment.

There are also block comments, which start with /* and end with */ and can span multiple lines.





Comments can used to temporarily disable a piece of code, which can be helpful for testing. For example, you can comment out lines of code one by one, each time re-running the script, to hone in on is throwing things off.


Structure & Punctuation

A statement is an instruction.  Just like an instruction in a human language, a JavaScript statement can be as simple as one word, or consist of multiple phrases (called expressions).  But unlike a person, if you instruct using perfect spelling and grammar, a computer will always do precisely as it’s instructed.

Scripts are made up of many statements, which are executed from top to bottom, left to right.

Each statement should end with a semicolon.  Semicolons indicate that the statement is complete, and should execute before proceeding to the next statement.

Whitespace (basically, spaces and line breaks) can impact functionality in many computer languages—but not in JavaScript.  In JavaScript, whitespace is used only for readability and has no functional impact.  One effect of this is that a single statement can span multiple lines.

This is a statement:

sentences = text.split( '. ' );


This code will do the exact same thing …


sentences=text.split('. ');


…and so will this:


'. '



Convention: Breaking up long statements into multiple lines is common practice, because it is easier to read (and prevents you from having to scroll horizontally as when reading scripts).


pro tip

There is one case where whitespace is actually functional: newlines can be used in place of semicolons to separate statements.  But this can cause issues in fringe cases, so as a general rule semicolons should always be used.



Intro to Functions


A function is a reusable piece of code, like a sub-script within the script.


Scripts are frequently organized into functions for a number of reasons:


  • Simplification of the main script code.  All the detailed code is abstracted into a descriptive function name, making the main script shorter and easier to read and follow.
  • If the same algorithm, calculation or process is used multiple times in a script, using a function minimizes the need for duplicate code.
  • It makes it easier to reuse bits of useful across multiple scripts.


Functions break up the top-to-bottom execution order of a script, because function code is run exactly where it is written.  Say you’re reading an article, and the writer begins the article with a glossary of jargon. You skim the glossary, not for comprehension, just to make yourself aware of the jargon you can expect to see.  Every time you encounter jargon, you jump back to the glossary to read the definition before continuing the sentence. The jargon would be function names, and the way you’re reading represents the nonlinear order of how scripts run.


First, you’ll see the function definition, which indicates the name of the function and its code:



function makeItRain(){
// Code to make it rain goes here.


But that code is not executed until the function is called. Functions are called using the function name, followed by a set of parentheses:



A function can be called repeatedly—and every time it’s called, the function code re-runs.

There are a variety of built-in functions available.  If you a function is called but you see no function definition, then it is a built-in function.  These work exactly the same way as custom functions.

You’ll learn more about functions later in the guide, but for now just understand that a function is a set of code that can be called from anywhere in the script.

// Assign code to the function name: 'makeItRain'.
function makeItRain(){
// Code to make it rain goes here.

// Make it rain once ...

// ... twice ...

// ... three times!

Get it? Just to make sure, here is one more example:


// This function "returns" the result of
// adding the numbers two and three.

function addTwoAndThree() {
return 2 + 3;

// Wherever this function is called, it will
// be replaced with the returned value.

addTwoAndThree(); // 5
1 + addTwoAndThree(); // 6


A value is a piece of data.

A value written directly into a script is said to be literal.

// a literal number three

A literal value is only available to the code once, exactly where it is literally written. In order to be accessed repeatedly (and possibly manipulated), a value must be assigned to a variable.



A variable is a named reference to a value.

A variable is created with the keyword var, and can be assigned a value using the equals sign.


// Create variable 'age'.
var age;
// Assign 'age' a value of three.
age = 3;


This can be combined into a single line:


var age = 3;


An existing variable can be re-assigned, which changes its value from that point forward. Oftentimes variables are assigned new values multiple times.


var age = 1;
// Variable 'age' equals one.

age = 2;
// Now variable 'age' equals two.

age = 3;
// Now variable 'age' equals three.

After it is created, a variable can be referenced using the variable name.

var age = 3;
var yrsOld = age;
// Now both 'age' and 'yrsOld' equal 3.

Convention: As seen in the example code above, both the variable value and type can be changed.  But in practice, it’s best for each variable to have the same value type throughout the entire script, to keep the logic easy to follow.

Variable Names

A variable’s name is how it is referenced throughout the script, used as a placeholder for the variable’s value.

How a variable is named has no functional effect on the script.  Names are chosen solely for readability, and should reflect the variable’s semantic purpose in the script.  Ambiguous names (like those used in many of the code snippets in this guide) should never be used in actual scripts.  One exception is that single-letter names are often given to variables that are simple counters.

Variable names can contain letters (case-sensitive), underscores, and dollar signs.  They can also contain numbers, but not as the first character.



Convention: Always start your variable names with a lowercase letter.  This convention will help avoid conflicts with most built-in variables, which generally start with uppercase letters.

Capitalize the first letter of each subsequent word in your variable name in a convention known as “lowerCamelCase” or “camelBackCase”. This keeps your variables readable without restricting you to single-word variable names.

There are some words that should never be used as a variable name, because they have special meaning in JavaScript.  You’ll learn about a few of these in this guide.


There are some words that should never be used as a variable name, because they have special meaning in JavaScript.  You’ll learn about a few of these in this guide.

  • null
  • true
  • false
  • undefined
  • NaN
  • Infinity
  • eval
  • arguments
  • var
  • break
  • case
  • catch
  • continue
  • debugger
  • default
  • delete
  • do
  • else
  • finally
  • for
  • function
  • if
  • in
  • instanceof
  • new
  • return
  • switch
  • this
  • throw
  • try
  • typeof
  • void
  • while
  • with
  • class
  • const
  • enum
  • export
  • extends
  • import
  • super
  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield



Built-In Variables

JavaScript has a few built-in variables that are always available.  You’ll learn about some of them in the next section, but know that these exist, and scripts should not use any of these names for custom variables:

  • Math
  • JSON
  • Function
  • Object
  • Array
  • Boolean
  • Date
  • String
  • Number
  • Error
  • EvalError
  • InternalError
  • RangeError
  • ReferenceError
  • SyntaxError
  • TypeError
  • URIError
  • RegExp
  • Promise
  • Set
  • Map
  • WeakSet
  • WeakMap



You remember functions, right? Let’s go over it again, this time building on your understanding of values and variables, and dig into what makes functions so useful beyond just being reusable.

A function is effectively a variable. Function names follow the same rules as variable names. But instead of a value, it has a set of code.  And instead of being referenced, it is called (which is just like referencing a variable, except with parentheses after the name).

Just as a reference to a variable is replaced with the variable’s value, a function call is replaced with the function’s returned value.  In the function code, a value is returned with the keyword return:


function whoAmI(){
   return "I don't know.";
whoAmI(); // "I don't know."

If a function doesn’t return anything it’s said to “return undefined.” (You’ll learn more about “undefined” in the following section.)

Functions can have input variables, which are defined as parameters in the function definition, whose values can be passed as arguments in the function call:


function theFunc( param1, param2 ){
   // Function code goes here,
   // which has access to the
   // values of arg1 and arg2
   // through the variable names
   // param1 and param2.
theFunc( arg1, arg2 );

Think of arguments as function “inputs”, which influence the function “output” (the return value).

function whoAmI( name ){
   return "I'm " + name + "!";
whoAmI( "Jax" ); // "I'm Jax!"


Functions also have access to variables that were created outside of the function.


var myName = "I don't know";
function myNameIs( name ){
   myName = name;
function whoAmI(){
   return "I'm " + myName + "!";
whoAmI(); // "I'm I don't know!"
myNameIs( "Jax" );
whoAmI(); // "I'm Jax!"

Although functions can access variables that were created outside the function, it’s generally best to avoid it. Keep functions self-contained by having them accept all neccessary values as parameters. This will make your code cleaner, easier to read, and easier to troubleshoot.

Global Functions

JavaScript has a set of built-in functions.  These are called global functions because they are available anywhere in any script.  Here are a few:

  • parseInt()
  • parseFloat()
  • isFinite()
  • isNaN()
  • decodeURI()
  • encodeURI()
  • decodeURIComponent()
  • encodeURIComponent()



There are also a variety of built-in functions that can only be called through variables, called methods.  A method is a function that is owned by and specific to a variable, and can only be accessed through that variables.  A method can be called by following the variable reference with a period, then the method like any other function call:

var name = "JAX";
name.toLowerCase(); // "jax"

Which methods are available on a particular variable is determined by the variable’s value type.  You’ll learn about various value types and their most useful methods in the next section.



There are other global functions made available as methods of built-in global variables called libraries.  Here are libraries you may encounter and example methods:

  • JSON (Reference)
    • JSON.parse()
    • JSON.stringify()
  • Math (Reference)
    • Math.round()
    • Math.sqrt()
There is no need to try to memorize any of the built-in functions/methods.  Documentation on each’s purpose, parameters, returned values, usage examples, and more are always a few keystrokes away in a wealth of online resources (see the Resources section).  Simply do a web search for “javascript” and function/method name.


The type of a value indicates how its data is structured and how it can be manipulated.

There are five basic types:

  1. Boolean
  2. Number
  3. String
  4. Regex
  5. Date

And two complex types, which can contain multiple values:

  1. Array
  2. Object


Pro Tip

There’s actually one more type: function.  (When I said that “a function is effectively a variable”, it wasn’t just a metaphor.) The function definition is the value, and function literals not assigned a function/variable name are called anonymous functions. Learn More.


There are also two special “blank” values, which don’t fall under any of the types above: null and undefined. Variables have a default value of undefined until they are assigned a value, and null is a generic blank value which can be used to explicitly indicate a variable intentionally has no value.  Example:


var name; // undefined
// 'name' is blank by default.

name = null;
// Now 'name' is explicitly blank.

null and undefined are the only values with no methods.

Each type has its own methods and own value literal syntax, so let’s take a look at each type:

Let’s review the five basic types of values.



There are two boolean values: true and false.

var jaxIsYoung = true;
var jaxIsOld   = false;



Number literals can be written as integers, decimals, or in exponential form.

var age     = 3;
var pi = 3.14159;
var leagues = 2e4; // 20,000



A string is text, consisting of zero or more characters.  String literals are written by surrounding the text with either single or double quotes.


var name     = 'Jax';
var greeting = "Hi, I'm Jax!";

When your string includes a single quote, you’ll need to use double-quotes to surround your string, or escape the single quote by preceding it with a backslash.  Vice-versa for a string containing a double-quote.

Here are some useful string methods.

trim() strips leading and trailing whitespace.


greeting = "   hi   ";
greeting.trim(); // "hi"

toLowerCase() and toUpperCase() convert all characters to a single case.


greeting = "Hello!";
greeting.toLowerCase(); // "hello!"
greeting.toUpperCase(); // "HELLO!"

indexOf() searches for specific text within the string (passed as an argument) and returns the numerical position of the matched text (first character considered the zeroth position), or -1 if the text is not present.


greeting = 'hi Philadelphia!';
greeting.indexOf('hi'); // 0

greeting = 'hey Philadelphia!';
greeting.indexOf('hi'); // 5

greeting = 'hey San Diego!';
greeting.indexOf('hi'); // -1

Note that none of these methods actually modify the variable’s value, but simply return the modified value.


greeting = "Hi";

greeting.toLowerCase(); // "HI"
// The above line returned "HI", but
//   the variable was not assigned
//   the returned value, so:
//   greeting = "Hi" (unchanged)

greeting = greeting.toUpperCase();
// This time we assigned the
//   returned value to the variable:
//   greeting = "HI"



You can find a reference of all string methods on MDN.

Strings also have a length property, which is not a function but just a number indicating number of characters in the string.

name = 'Jackson';
// name.length = 7

name = 'Jax';
// name.length = 3

name = '';
// name.length = 0




A regex, or regular expression, is a special query pattern used for searching and matching strings. You may already be familiar with regex because it can be used in many platforms and applications.  If you are not familiar with regex, check out this quick-start guide.

In JavaScript, a regex literal is written by enclosing the regex expression with forward-slashes.


// Regex to match start of a URL.
var matchUrl = /^https?:/;


If a forward-slash is part of the regex expression, it needs to be escaped by preceding it with a backslash.


// Regex to match start of a URL.
matchUrl = /^https?:\/\//;


Regex flags can be added after the rightmost slash.


// Now regex is case-insensitive
// since we added the 'i' flag.
matchUrl = /^https?:\/\//i;



The same regex can also be created this way:

myRegex = new RegExp( '^https?://', 'i' );


This is useful for when the regex expression is not predetermined.


In JavaScript, regex can be used to:

Determine if a string matches a pattern:


/^http:/.test(""); // true
/^http:/.test("not a url"); // false


Extract pattern matches from a string (learn about the return value here):


var m = /(.*)=(.)/g.exec("2+2=4");
// m = ["2+2=4", "2+2", "4"]



A date is a timestamp, specific to the millisecond.

A date can be created by setting values for year, month, day, hour, minutes, seconds, and milliseconds.


var birthday = new Date( 2013, 4, 4, 4, 3, 1 );
// May 4, 2013 @ 4:03:01


But only year and month are required; the date need only be set to the specificity needed by the script.


var birthday = new Date( 2013, 4, 4 );
// May 4, 2013


Note that January is zero, and December is eleven.  If you passed twelve as the month value, it would map to January of the following year.


var xmas = new Date( 2016, 12, 25 );
// Jan 25, 2017 <- whoops, not xmas!
Dates can also be created using a single string that specifies the date, instead of multiple number values. But if the string is not formatted correctly, the date may have an unexpected value.  See examples for acceptable formats here.

If a date is created without setting any values, it will default to the current date/time (as set by the computer on which the script is running).


var now = new Date();


This allows us determine how far in the future or past a second date is, which can be very useful.


var now = new Date();
var xmas = new Date( 2016, 11, 25 );
var millisecondsAway = xmas - now;
var daysAway =
millisecondsAway / 1000 / 60 / 60 / 24
JavaScript dates are timezone aware. This is important to keep that in mind when dealing with date values from multiple sources.




An array is an ordered collection of values.


nicknames = [ 'Jax', 'Jah', 'Jay' ];


An array’s values are mapped, or indexed, by integers.  Indexing is done automatically, starting at zero, incrementing for each item.  So the first value is at index 0, the second at index 1, and so on.

Each item in an array can be accessed by placing the index within square brackets after the variable reference.


nicknames[0]; // 'Jax'
nicknames[1]; // 'Jah'
nicknames[2]; // 'Jay'
Starting at zero instead of one may seem strange to you, but it is very common in the world of computer science.  Don’t worry; you’ll get used to it pretty quickly!

Because they are indexed numerically, arrays have an intrinsic order.  So, arrays are well-suited to represent an ordered dataset where order matters (such as a queue or an alphabetical list).

Arrays can contain any number of values—even zero.


nicknames = []; // empty array
// No nicknames! Just call me 'Jackson'.

To add an item onto the end of an existing array, use the push method:


nicknames = [];
// Okay, you can call me 'Jax'.
nicknames.push( 'Jax' );
// nicknames = [ 'Jax' ];

To remove the last item in an array (and return it), use the pop method:


// nicknames = [ 'Jax' ];

nicknames.push( 'Jackie' );
// nicknames = [ 'Jax', 'Jackie' ]
// I will not answer to 'Jackie'!

nicknames.pop(); // 'Jackie'
// nicknames = [ 'Jax' ]

You can find a reference of all array methods on MDN.

Similar to strings, arrays have a length property, which is not a method, but a special property that always indicates the number of items in the array:


nicknames = [ 'Jax' ];
// nicknames.length = 1;
nicknames.push( 'Jah' );
// nicknames.length = 2;


This is how you operate on all items of an array (this contains operators and a loop which is covered in following sections):


// nicknames = [ 'Jax', 'Jah' ]
var i, nickname;
for( i=0; i < nicknames.length; i++ ){
nickname = nicknames[i];
say( 'Some call me '+nickname+'.' );
// Some call me Jax.
// Some call me Jah.

Values in an array can be of any type—even other arrays.  An array within an array is known as a two-dimensional array.  If a row in a spreadsheet was an array, the entire sheet would be a 2-D array.


var table = [
[ 'A1', 'B1' ],
[ 'A2', 'B2' ],
[ 'A3', 'B3' ],
myArray[0];   // [ 'A1', 'B1' ]
myArray[0][0]; // 'A1'
myArray[2][1]; // 'B3'
myArray[2][2]; // undefined




An object is an unordered collection of key/value pairs.


var kid = {
 'age'       : 3,
 'name'      : 'Jackson',
 'nicknames' : [ 'Jax', 'Jah' ]


Remember that white space just used to format code.  This code creates the same exact object:


var kid = {'age':3,'name':'Jackson'};


An object’s values are mapped by strings called keys.  When a value is added to an object, it is added using a particular string, and then that string can be used to request that particular value from the object. That string is the value’s key.  If a coatcheck were an object, the coats would be values, and the numbers the attendant uses to keep track of coats would be keys.

Items in an object can be accessed with the same bracket-syntax used for an array:


kid['age'];  // 3
kid['name']; // 'Jackson'


Items in an object can also be accessed can also be accessed using dot notation:


kid.age;  // 3; // 'Jackson'


Either syntax can also be used to add a new key:


kid.nicknames = [ 'Jax', 'Jah' ];


Or to change the value of an existing:


kid.nicknames = [ 'Jax', 'Jah' ];


This is how you operate on all keys or values of an object (this contains operators and a loop which is covered in following sections):


// kid = {'age':3,'name':'Jackson'}
var key, value;
for( key in obj ){
value = kid[key];
// Code to deal with a
//   key/value pair goes here.
say( 'My' + key + ' is ' + val );

// My age is 3.
// My name is Jackson.


Like an array, an object can contain any number of values, and those values be of any type, including other arrays and objects.


var kids = {
   'firstborn' : {
       'name' : 'Jackson',
       'age'  : 3
   'middleChild' : {
       'name' : 'Jazmine',
       'age'  : -0.65
   'theBaby' : {
       'name' : 'Isaiah',
       'age'  : undefined
kids.firstborn.age; // 3;  // 'Isaiah'


Objects are useful for representing a singular item or concept (e.g. a product, with name, sku, and price attributes), or storing a collection that has a specific unique id system (e.g. a set of product objects, mapped by their skus).


pro tip

Any given dataset can be represented by either an array or an object. But, usually one is better suited than the other, based on the structure of the dataset.  For instance, the previous example would be better represented as an array of objects:

var kids = [
       'name' : 'Jackson',
       'age'  : 3
       'name' : 'Jazmine',
       'age'  : -0.65
       'name' : 'Isaiah',
       'age'  : undefined



There are a number of operators in JavaScript, many of which reflect how they would be written in a mathematical expression.  However many can be used for types other than numbers.


Mathematical Operators

+ add
- subtract
* multiply
/ divide


As you may have guessed, these are used with numerical values.

To use exponents/roots, do not use a caret (^)!  The caret is an advanced operator that does something totally different (so using it will allow your script to run, but return incorrect values—an error which can be hard to catch).  Instead use the built-in function: Math.pow(base,exponent).



Expressions with multiple mathematical operators will be evaluated according to the standard mathematical order of operations. In case you don’t remember PEMDAS, here’s a refresher:  Expressions within parentheses are evaluated first, then exponents, then multiplication/division, then addition/subtraction; other than that expressions are evaluated left-to-right.

If using multiple operators in a single expression, it’s wise to break the expression down into pieces using parentheses.  Even if a complex expression is evaluated correctly according to order of operations, using parentheses can improve readability, making it easier to read and understand the expression.  (Double up on readability by using parentheses AND explaining a complex expression using a comment!)



pro tip

There is a special division operator called “modulo”: %.  It is like division, but instead of returning the exact division result it does integer division and returns the remainder. It is useful for determining whether a number is a factor of another number.


Concatenation Operators

The plus sign doubles as a concatenation operator for strings:

+ concatenate two strings
+= append to a string variable



name = "Jax";
greeting = "Hi!"
greeting += " I'm " + name + ".";
// greeting = "Hi! I'm Jax."


If the concatenation operator is used between a string and another type, the non-string value will be coerced into a string.



age = 3;
greeting += " I'm " + age + " years old.";
// greeting = "Hi! I'm Jax. I'm 3 years old."



Comparison Operators

== Equals
!= Does not equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to


Comparison operators always return a boolean value, and are usually used in ‘if’ statements (if statements are covered in the next section).


Logical Operators

&& and
|| or
! not


Like comparison operators, logical operators always return a boolean value.


jaxIsYoung = true;
jaxIsOld   = false;
jaxIsYoung && jaxIsOld;  // false
jaxIsYoung || jaxIsOld;  // true
jaxIsYoung && !jaxIsOld; // true


Generally these are used in if statements, which are covered in the following section called ‘Conditionals’.


Increment/Decrement Operators

=+ Increment
=- Decrement
++ Increment by 1
-- Decrement by 1


These four are special because they actually modify the value of the variable.



age = 3;
// age = 4
// age = 5
age =+ 30;
// age = 35
// age = 34
age =- 31;
// age = 3


pro tip

All the above increment/decrement operators also return the variable’s prior value (its value before being incremented/decremented). There are also the += and -= operators, which behave the same as above but they return the variable’s new value.  Similarly, the ++ and -- can be placed before the variable reference to return the new value. The return values of these operators only matter if they are used within a greater expression; the return value is discarded if used as the entire statement, as in the examples above.



I’ll tell you a secret: conditional structures are the key to having a robust script.  Conditional structures enable multiple cases to be handled within a single script.

There are two primary types of conditional structures: if/else blocks and loops.


If/Else Blocks

An if block (or if statement) executes a block of code only if a given condition expression evaluates true.


if( jax.age < 5 ){
jax.goTo( 'daycare' );

The condition will pass for values other than the boolean value true, which are considered “truthy”: non-empty strings, non-zero numbers, and any date, regex, object, or array (even if the object or array is empty).


An else block can be added to the end of the if block in order to execute an alternate set of code in case the expression evaluates to be false.


jax.age = 10;
if( jax.age < 5 ){
// This code will NOT execute.
jax.goTo( 'daycare' );
} else {
// This code WILL execute.
jax.goTo( 'school' );


More numerous cases can be handled by chaining a series of if/else blocks together:


if( jax.age < 5 ){
jax.goTo( 'daycare' );
} else if( jax.age < 18 ){
jax.goTo( 'school' );
} else if( jax.age < 60 ){
jax.goTo( 'work' );
} else {


pro tip

If there are multiple possible values for a single variable that a script needs to check for, a switch statement can be simpler than a series of if statements.  Read about switch statements here.



A loop is used to run a specific set of code repeatedly until a specific condition is met.

The most common type is the for loop, which is usually used to loop through each item in an array or object.

Here is an example of looping through an array:


// nicknames = [ 'Jax', 'Jah' ];
var i, nickname;
for( i=0; i < nicknames.length; i++ ){
   // Code here will be run for
   //   each nickname.
   nickname = nicknames[i];
   say( 'Some call me '+nickname+'.' );
// Some call me Jax.
// Some call me Jah.


And an example of looping through an object:


// kid = {'age':3,'name':'Jackson'}
var attribute, value;
for( attribute in kid ){
   // Code here will be run for
   //   each attribute of 'kid'.
   value = kid[attribute];
   say( 'My' + key + ' is ' + val );

// My age is 3.
// My name is Jackson.


The other type of loop is the while loop, which is used when the number of times the loop code needs to execute is unknown (as opposed to for loops, which run code a specific number of times).


function canLiveAtHome( person ){
if( person.age < 18
|| person.job == "student"
|| person.paysRent ){
return true;
} else {
return false;

var kid = new Person( "Jax" );

while( canLiveAtHome( kid ) ){
   // As long as canLiveAtHome()
   //   returns true, then ...

// Once canLiveAtHome() returns
//   false, then ...



Until you are a bit more practiced at reading JavaScript, you will not remember all the concepts and syntax above.  That’s okay!  Even experienced developers have not memorized all of the names, parameters, and exact return formats of the many built-in functions.

Documentation on all of this is always a few keystrokes away in a wealth of online resources.  Simply search “javascript” and the syntax keyword or function/method name and you will find plenty of reference articles.

Often the first search result, w3schools’ articles are often high-level and non-comprehensive.  The detailed documentation on MDN (Mozilla Developer Network) is a top choice for many developers and avid learners.


You can also find lots of specific examples and answers to all sorts of issues in forums like Stack Overflow.


If you’re getting an error and you don’t know why, search for the error message verbatim to find how other people fixed it.  If you get no results, try the search without custom variable names, filenames, and line numbers.

Chapter 4: Advanced Google Ads Scripts Code

This section will help you understand how scripts actually work, so you can customize scripts for your needs beyond what the included settings allow (or even write your own Google Ads Script).

This section assumes you already understand basic JavaScript. (If you’re not familiar with JavaScript yet, start with the previous chapter.)

Global Objects

There are a few custom built-in objects that are available to any Google Ads script.  These encompass all the necessary functions for working with your Google Ads data, other Google services, and a few handy tools.

App Objects

The “app” objects are built-in objects that make it easy to interact with a few Google platforms. These app objects are available to Google Ads scripts by default:

  • AdWordsApp is central to any Google Ads script, providing read and write access to AdWords configurations and report data.  You’ll learn more about it in the next section.
  • MccApp (My Client Center accounts only) is used to run scripts across an entire MCC.
  • SpreadsheetApp allows you to read from and write to Google sheets.
  • DriveApp lets you create and manage files in Google Drive.
  • MailApp lets you send, read and manage messages in Gmail.
  • ChartApp allows you to create charts though Google Chart Tools.



You can enable additional app objects for advanced integrations:

  • Analytics
  • BigQuery (for Google Analytics 360 customers)
  • Calendar
  • FusionTables
  • Prediction
  • ShoppingContent
  • Tasks
  • YouTube & YouTubeAnalytics

Utility Objects

There are also a number of built-in utility objects, which provide a variety of useful functions for performing calculations, working with various data formats, and connecting to external services.

  • BigNumber
  • Jdbc
  • UrlFetchApp is used to interact with external APIs over http.
  • Utilities
  • XmlService
The standard Math and JSON libraries are available as well.  When troubleshooting either of these, it can be easier to use the console in your browser to do lots of testing and tweaking for small bits of code.



All of these are JavaScript objects, but they’re not used to store data (by you—the script editor—anyway).  All of their data is accessed via methods.  You can explore all the available methods within these objects in Google’s documentation (under ‘Script Services’ in the left navigation) and by using the autocomplete feature in the Google Ads scripts editor.


There is also the Logger object, which is only for debugging.  It offers a single method: Logger.log(), which prints its passed argument as a string to the Google Ads Script editor’s execution log.  (You’ll learn how to view the log in the next section.) When the script is not running correctly, using Logger.log() allows you to trace the order of execution and make sure the values of variables are what you expect.



The AdWordsApp global object is the core of the Google Ads scripts API.  It provides access to both management and reporting.

All of its methods return objects, and those returned objects also have methods that return other objects.  Each object is distinguished by its intended use.  In Google’s documentation, these uses are identified by these terms:



Google Ads data and configurations are represented in a script as Entities.  Here are some of the core Entities:

  • Ad
  • AdGroup
  • AdGroupCallout
  • AdGroupReview
  • AdGroupSitelink
  • AdParam
  • AdSchedule
  • Audience
  • BiddingStrategy
  • Budget
  • Callout
  • Campaign
  • CampaignCallout
  • CampaignReview
  • CampaignSitelink
  • DisplayKeyword
  • ExcludedAudience
  • Keyword
  • Label
  • MobileApp
  • NegativeKeyword
  • PhoneNumber
  • Placement
  • Platform
  • ProductAd
  • ProductGroup
  • Review
  • ShoppingAdGroup
  • ShoppingCampaign
  • Sitelink
  • Topic

Each of these are objects, and each of them have corresponding Selector and Iterator objects to allow accessing those Entities.  Some of the Entities also have corresponding Builder objects, which create new Entities.

You can find the details of the methods for each Entity, as well as the methods of their corresponding Selectors, Iterators, and Builders in the AdWords documentation.

Here are some additional Entities:

  • Account
  • ManagedAccount (MCC only)
  • AccountCallout
  • AccountMobileApp
  • AccountReview
  • AccountLabel (MCC only)
  • AccountExtensions
  • AdCustomizerItem
  • AdCustomizerSource
  • AdGroupExtensions
  • AdGroupMobileApp
  • AdGroupPhoneNumber
  • CampaignExtensions
  • CampaignMobileApp
  • CampaignPhoneNumber
  • ExcludedDisplayKeyword
  • ExcludedLocation
  • ExcludedPlacement
  • ExcludedPlacementList
  • ExcludedTopic
  • ExtensionSchedule
  • Extensions
  • NegativeKeywordList
  • SharedExcludedPlacement
  • SharedNegativeKeyword
  • AdGroupBidding
  • AdGroupOperation and other *Operation
  • AdGroupUrls and other *Urls
  • BulkUploads
  • CsvUpload
  • FileUpload
  • AdWordsDate
  • ExecutionInfo
  • Stats
  • AdGroupDisplay
  • CampaignDisplay
  • Display
  • Report
  • ReportColumnHeader
  • ReportRow
  • ReportRowIterator
  • ProductBrand
  • ProductBrandBuilder
  • ProductBrandOperation
  • ProductCategory
  • ProductCategoryBuilder
  • ProductCategoryOperation
  • ProductChannelExclusivity
  • ProductChannelExclusivityBuilder
  • ProductChannelExclusivityOperation
  • ProductChannel
  • ProductChannelBuilder
  • ProductChannelOperation
  • ProductCondition
  • ProductConditionBuilder
  • ProductConditionOperation
  • ProductCustomLabel
  • ProductCustomLabelBuilder
  • ProductCustomLabelOperation
  • ProductGroupBuilderSpace
  • ProductItemId
  • ProductItemIdBuilder
  • ProductItemIdOperation
  • ProductType
  • ProductTypeBuilder
  • ProductTypeOperation
  • Address
  • Targeting
  • TargetedLocation
  • TargetedProximity
  • ExecutionResult
  • ManagedAccountStats (MCC only)

Accessing Entities

Selectors are used to retrieve a list of Entities.

Each Entity has its own type of Selector.  Some Entity Selectors are accessed directly from the AdWordsApp object, and others are accessed using methods in the Entity that contains them.



// ads Selector
var adsSelector =;

Selectors have methods called conditions that filter and sort the list of retrieved Entities.

Selectors for various Entities may have unique condition methods specific to that Entity, but most Selectors have a few core condition methods:

  • withIds()
  • forDateRange()
  • orderBy()
  • withLimit()
  • withCondition()


Only Entities that match every given condition are retrieved.  You can apply multiple conditions one-by-one:


var adsSelector =;
adsSelector =
adsSelector.withCondition("Clicks < 2");
adsSelector =


Or string them together:


adsSelector =
.withCondition("Clicks < 2")
Selector conditions are optional, but using Selectors without conditions can cause your script to run much more slowly than necessary.  It may be easier to select all instances of a particular Entity, then act conditionally based on specific parameters later in the script, but it’s worthwhile to use Selector conditions instead.
You can only process 50K Entities using a single Iterator, and 250K Entities total across the entire script. (Details)

All Selectors have a get() method which returns an Iterator, which is used to loop through the retrieved Entities and access each Entity.

Usually, to traverse a list and handle each item one-by-one, we would use a for loop.  But in Google Ads scripts, Iterators provide the next() and hasNext() methods, which allow us to use a simplified while loop.



var adsSelector =;
var adsIterator =
while( adsIterator.hasNext() ){
var ad =;
// do stuff with `ad`


The next() method of Iterators returns a reference to an individual Entity.  The first time it’s called for a particular Iterator, it will return the first Entity in the list, and every subsequent call gets the next Entity in the list.

It’s important next() is only called at one point within a loop, or else Entities could be inadvertently skipped.  If you do want to skip an Entity for any reason, use the continue command inside the loop.

Editing Entities

An Entity can be modified using a reference to an individual Entity (returned by an Iterator’s next() method).  Each Entity has its own methods, which you can explore in the documentation (under AdWordsApp on the left).



var ad =;

Creating Entities

A new Entity can be created using a Builder.

Unlike Selectors and Iterators, Builders are only available for a subset of Entities:

  • AdCustomizerItem
  • AdCustomizerSource
  • Callout
  • MobileApp
  • PhoneNumber
  • Review
  • Sitelink
  • AdGroup
  • Ad
  • Audience
  • DisplayKeyword
  • Placement
  • Topic
  • Keyword
  • ExcludedPlacementList
  • NegativeKeywordList
  • ShoppingAdGroup
  • ProductAd

Builders are created using the parent Entity under which the new Entity will be created.  These parent Entities have methods that look like new*Builder(), which return the Builder. Example:


// Create an Ad Group Builder
var campaign =;
var adGroupBuilder =



Using the Builder, then set the Entity attributes using methods specific to that Entity’s Builder.  You can see all the methods in Google’s documentation (e.g. Ad Builder).

Once the attributes are set, call the Builder’s build() method to create an Operation.  Calling the getResult() method of the Operation object will create and return a reference to the new Entity.


// Create an Ad Group
var adGroup =
A single script cannot create more than 250K Entities (Details).
pro tip
Creating Entities can fail for a number of reasons.  Use the getErrors() method of the Operation (which returns an array of strings) to check for problems, and log errors in a spreadsheet or send an email notification.
pro tip
Rather than calling Operation object methods as soon as the Operation is created, place all Operations into an array and then loop through to getResults() or getErrors() once all Operations are created.  (This allows the script to run more efficiently by leveraging back-end optimizations.)

What’s Next?

Make sense?  If you’re ready to get testin’, proceed to the next chapter and find the best script for you!

Going Further

This overview should be a strong starting point to help you get cracking with some pre-built scripts!  If you’re interested in doing heavy customization or writing your own scripts, you’ll need to learn more about the nuances of Javascript and get closely acquainted with Google’s Google Ads Scripts documentation.

If you’re looking to integrate with other Google services, be sure to acquaint yourself with the various quotas before designing your scripts.

Chapter 5: Which Google Ads Script Do I Need?

Okay, so now you know all about the anatomy of a script and how it works. But how does this apply to you? Check out our top script list to help you find the perfect Google Ads script to practice based on the account problems you’d like to solve! Are you a beginner, expert, or somewhere in between? We have an Google Ads script for you.

  • Link Checker (Level: Easy)
    • This easy-to-use script scans through our final URLs to find any that are pointing to non-existent (404) pages. You don’t want to be spending money driving users to dead pages, right? We believe that this script should be applied to EVERY account that you manage.
    • Link Checker – Manager Account (Level: Easy)
      • This extends the single account Link Checker script to run for multiple accounts under a manager account.
  • Account Summary (Level: Easy)
    • Tired of loading each of your clients accounts every morning to check yesterday’s performance? Use this script to have your daily account performance pulled into a GSheet AND emailed to you. You can also make this a client-facing report for those clients who like daily performance updates.
  • Bid to Position (Level: Easy)
    • For those without advanced PPC tools such as Acquisio or Marin, this tool can adjust your keyword bids to help position your ads in the ad position that works best for you. Remember, #1 ad position isn’t always the best position for every client/industry.
  • Negative Keyword Conflicts (Level: Easy) 
    • Proactively negating inefficient terms can be an important part of account management. As an account grows and keyword lists expand, it is important to ensure that you are not blocking keywords from matching relevant search queries, affecting your account efficiency. This script will check whether the negative keywords in an account block any target keywords and deliver the finding in a spreadsheet via email. Note: A similar feature is now available within the Google Ads platform. However, the Seer team continues to find value in this script as the emailed spreadsheet layout of its findings lends itself to easy review & implementation. 
  • Advanced Google Ads Budget (Level: Easy)
    • Budgets got you stressed? This script has your back! There are three areas that this script will lighten your load: enforcing account budgets, maintaining monthly budgets, and applying small budgets to tests. Why stress when you can utilize automation to make your budgets more flexible?
  • Disapproved Ads Alerts (Level: Easy)
    • This super easy-to-implement script is pretty self-explanatory. Implement this to know the moment your ad has been snagged on a disapproval.
  • Pause Campaigns When Site is Down (Level: Intermediate)
    • Nothing is worse than paying for a click, only for it to drive to a dreaded 404 page. How could that be? You QA‘d this link before the campaign went live! Well, as your client’s business evolves they may have back-end changes made to their site or a site could go down overnight while you sleep, dreaming of your treasured CVR. This script will detect when your site is out of commission and automatically pause your campaigns to save you from wasting your budget.
  • Search Query (Level: Intermediate)
    • This mid-level script helps to not only automate the process of pulling and analyzing SQRs, it also can help to implement new keywords and ads based on thresholds that you set. You can use this script to create some nifty tricks for automatically creating ad groups for those certain search queries that are absolutely killing it for your conversion rates and CPA’s!
  • Keyword Performance (Level: Intermediate)
    • Do you have keywords that have bad quality score? That’s a silly question, of course you do! This script will help automate the process of finding those keywords that are sucking your budget dry due to poor quality score.
  • Sale Countdown (Level: Intermediate)
    • Humans love things when their a sense of scarcity. Skip waiting for your ads to pass through ad approval and use this script to update your countdown values without the need of sending your ad back through the approval process.
  • Account Anomaly (Level: Intermediate)
    • Decide to launch a non-modified broad match keyword to gain more insights about how your customers are searching? As PPC’ers, we know how valuable (and dangerous) this strategy can be. Use this script to have alerts sent to you by email if your account is performing significantly different than it usually is.
  • Auction Insights (Level: Advanced)
    • This non-traditional script helps to visualize auction insights data over time to help you understand what has been going on in your industry. Use this to see which competitors have come and gone over time and if you’re really handy, you can use this to spy on your competitors spend and see when they typically exhaust their budgets.
  • Bid by Weather (Level: Advanced)
    • Do you notice an uptick in account performance when its raining or snowy? How about when it’s sunny? If so, use this script to automatically adjust your bids when users are in areas with your preset weather conditions. I mean, who buys umbrellas when it’s NOT raining?
  • Multi Bidder (Level: Advanced)
    • This difficult to set up (but super powerful) script gives you the ability to make keyword bid adjustments based of of multiple variables. You can even use this script to set specific keywords to first page or top of page cpc’s, if you’re comfortable in trusting Google for those values.
  • Ad Customizer (Level: Advanced)
    • How would you like to be able to dynamically insert your stock numbers in your ad copy? By showing users how many of a product you have left, you can help nudge them to complete their purchase. Using this script, plus some cloud hosted inventory data, you can have your ad text to be updated to include values reflecting your current stock of a product. Can you believe there are still people who say dynamic insertion is a bad thing? Shame on them.
  • Dayparting Automation (Level: Advanced)
    • Not only is it a boring and monotonous task pulling and analyzing dayparting data, it’s complicated to upload and you’re bound to miss a time period which can throw off your entire account’s performance. This script from Brainlab via Search Engine Land uses fancy data smoothing to eliminate anomalies, it creates heatmaps, and it shows your data across a basic line graph. Then it uses your data to make up to 24 bid adjustments daily (4 times more than Google Ads permits through their interfaces). This one is tricky to get going, but it can really help out those clients/companies who have performance that varies across each hour.

Chapter 6: Implementing Google Ads Scripts

Got an Google Ads Script in mind? Great! Our next lesson plan will walk you through the process of implementing your script. Watch this video, or read below for the step-by-step instructions.

  1. Once you have either created or selected a pre-made script that fits your account needs, the next step is to implement.  Google Ads Scripts can be implemented in the “Bulk Operations” options which can be located in the lower half of the left-hand column in the Google Ads UI at both the MCC-level and account-level.

AdWords UI Bulk Operations

  1. When you click-through the “Bulk Operations” link, you’ll be brought to the Bulk Operations menu screen where you’ll need to select the “Create and Manage Scripts” Link.

AdWords UI create and manage scripts

  1. Once clicked through, the “Create and Manage Scripts” will bring you to a screen that allows you to manage new and existing scripts, and see run-time logs for any past or presently active scripts. Since we’re implementing a new script, you’ll want to click the “+Script” button to create a new script: 

AdWords UI add script button

  1. You’ll then be directed to the scripts editor page, which will allow you to copy, paste, and manipulate scripts directly within the AdWords UI. This screen will also allow you to preview scripts to test them for functionality before saving and completely implementing. Please note that in order to fully preview and save a script, you must click the “Authorize Now” button which gives the script permission to run automatically on your behalf. Once on this screen you’ll want to follow these steps:
    • Choose a name for your script
    • Paste or hard code your script into the body of the editor
    • Edit script configuration settings as needed.
    • Authorize the script to run within your account on your behalf
    • Preview your script to test for errors/functionality
    • Save script once you’re happy with its performance
    • Close script editor (or choose run script now if you’d like)

Scripts editor

  1. Once your script has been previewed and saved, you should create a script run schedule where you can select the frequency in which you would like your script to run. Options include: one time, hourly, daily, weekly, or monthly run schedules. You can also layer in hour of day that you would like your script to run on a recurring basis.

Chapter 7: Google Ads Scripts Tips

Getting the hang of it? Here are our top 9 free tips for all levels—beginners to professionals—to keep in mind as you begin working with Google Ads Scripts.

  1. Google Ads scripts can sometimes take a long time to run—think a half hour to an hour! It’s possible your script could time out and updates won’t be complete. Always confirm that your script ran by checking progress in the log section.
  2. Don’t just set and forget. While it’s nice to sit back and let scripts do some of the work, you’ll still want to keep an eye on your account and ensure it’s making the changes you recommended.
  3. Scripts cannot be undone. Backup your account by downloading the account from editor before you implement the script so you can reupload the account without the script if necessary.
  4. Implement scripts at the MCC-level (My Client Center—utilized to manage and edit scripts across multiple accounts at scale) to protect code from clients and maintain control (credit to @siliconvallaeys). If you have more than 50 accounts in your MCC, you can use the MCC Manager template that Google released.
  5. View common script examples by clicking the “Show Examples” button while you’re editing. Copy the example and edit from there!
  6. Keep your naming process consistent throughout the script to avoid confusion.
  7. Leave comments directly within the script to help track changes and add context. It makes things easy when working with a team or making any changes to a script.
  8. Always check the comments/feedback section for any potential bugs/fixes if you decide to use a script posted online.
  9. Reference Google’s developers community forum for help if you’re running into any script problems.

Chapter 8: Troubleshooting Google Ads Scripts

We have all been there; you implement a script, preview it just to make sure everything is working properly then you hit that “ERROR” in the middle of your preview process. Naturally, this means the script will not work and you need a solution. But where do you turn? Below we will cover a few common errors that we at Seer have come across during the implementation process and how to fix them.

  1. Specify the date range. If the date range is input incorrectly, the script will stop running.
  2. Specify the campaign. Ensure you are pulling the correct data into your report
  3. Using destination URL instead of final URL. Older versions of scripts that call for destination URLs are no longer supported; change all instances to final URL
  4. Missing semicolons. These are sometimes mistaken with periods; ensure all semicolons are noted to allow the script to know where the expression ends.
  5. The code is case sensitive. You may receive an error notification that you are attempting to use an undeclared variable.

Chapter 9: Additional Google Ads Scripts Resources

What’s Next?

Now that you know what AdWords Scripts are, what they look like, what script is right for you, and how to implement scripts, go on…try implementing one on your own! Start making your AdWords life easier allowing for you to focus on your overall strategy. While you’re at it, check out some of our favorite scripts libraries: Free AdWords Scripts.comGoogle AdWords Scripts Solutions, and Google AdWords Code Snippets.

Seer Scripts Team

If you have any further questions related to scripts, feel free to contact our Seer Scripts Team. We would love to hear from you!


We love helping marketers like you.

Sign up for our newsletter to receive updates and more: