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
Structure
Google Ads Scripts generally follow this layout:
LicenseAny 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 // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. |
MetadataThe 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 * https://developers.google.com/adwords/scripts/docs/solutions/ad-performance * for more details. * * @author AdWords Scripts Team [adwords-scripts@googlegroups.com] * * @version 1.0 * * @changelog * - version 1.0 * - Released initial version. */ |
SettingsThe 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: tipIn 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. var RECIPIENT_EMAIL = 'email@example.com'; // URL of the default spreadsheet template. This should be a copy of // https://goo.gl/21FW5i var SPREADSHEET_URL = 'INSERT_SPREADSHEET_URL_HERE'; |
The Rest of the CodeEverything 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.', spreadsheet.getUrl()); 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()); spreadsheet.getRangeByName('account_id_headline').setValue( AdWordsApp.currentAccount().getCustomerId()); spreadsheet.getRangeByName('account_id_final_url').setValue( AdWordsApp.currentAccount().getCustomerId()); 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()); if (RECIPIENT_EMAIL) { MailApp.sendEmail(RECIPIENT_EMAIL, 'Ad Performance Report is ready', spreadsheet.getUrl()); } } /** * 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 = [ segmentName, 'Num Ads', 'Impressions', 'Clicks', 'CTR (%)', 'Cost' ]; rows.push(header); var segmentMap = {}; // Compute data. var adSelector = AdWordsApp.ads() .forDateRange('LAST_WEEK') .withCondition('Impressions > 0'); var adIterator = adSelector.get(); while (adIterator.hasNext()) { var ad = adIterator.next(); 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.numAds++; 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 = [ key, segmentMap[key].numAds, segmentMap[key].totalImpressions, segmentMap[key].totalClicks, ctr.toFixed(2), segmentMap[key].totalCost]; rows.push(row); } } sheet.getRange(3, 2, rows.length, 6).setValues(rows); } |
Editing for Basic CustomizationMany 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. var RECIPIENT_EMAIL = 'email@example.com'; // URL of the default spreadsheet template. This should be a copy of // https://goo.gl/21FW5i var SPREADSHEET_URL = 'INSERT_SPREADSHEET_URL_HERE'; |
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!
tip
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.
tip
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
note
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.
Syntax
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.
tip
Java and JavaScript are commonly confused, but they are completely different languages.
Comment
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.
/*
This
is
a
block
comment.
*/
tip
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:
sentences
=
text
.split(
'. '
)
;
tip
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:
makeItRain()
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 ...
makeItRain();
// ... twice ...
makeItRain();
// ... three times!
makeItRain();
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
Values
A value is a piece of data.
A value written directly into a script is said to be literal.
// a literal number three
3;
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.
Variables
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.
tip
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.
tip
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.
|
|
|
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:
|
|
Functions
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!"
tip
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()
Methods
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.
Libraries
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:
tip
Types
The type of a value indicates how its data is structured and how it can be manipulated.
There are five basic types:
- Boolean
- Number
- String
- Regex
- Date
And two complex types, which can contain multiple values:
- Array
- 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.
Boolean
There are two boolean values: true
and false
.
var jaxIsYoung = true;
var jaxIsOld = false;
Number
Number literals can be written as integers, decimals, or in exponential form.
var age = 3;
var pi = 3.14159;
var leagues = 2e4; // 20,000
String
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!";
tip
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
Regex
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;
tip
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("http://t.co"); // 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"]
Date
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!
tip
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
tip
Arrays
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'
tip
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
Objects
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
kid.name; // '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
kids.theBaby.name; // '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
}
];
Operators
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.
tip
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.
tip
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 |
Example:
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.
Example:
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.
Example:
age = 3;
age++;
// age = 4
age++;
// age = 5
age =+ 30;
// age = 35
age--;
// 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.
Conditionals
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' );
}
tip
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 {
jax.retire();
}
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.
Loops
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 ...
kid.feed();
kid.clothe();
kid.love();
}
// Once canLiveAtHome() returns
// false, then ...
kid.kickOut();
kid.love();
Conclusion
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.
tip
You can also find lots of specific examples and answers to all sorts of issues in forums like Stack Overflow.
tip
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.
tip
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
Tip
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.
AdWordsApp
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:
Entities
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.
Example:
// ads Selector
var adsSelector =
AdWordsApp.ads();
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 =
AdWordsApp.ads();
adsSelector =
adsSelector.withCondition("Clicks < 2");
adsSelector =
adsSelector.forDateRange("TODAY");
Or string them together:
adsSelector = AdWordsApp.ads()
.withCondition("Clicks < 2")
.forDateRange("TODAY");
Tip
tip
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.
Example:
var adsSelector =
AdWordsApp.ads();
var adsIterator =
adsSelector.get();
while( adsIterator.hasNext() ){
var ad = adsIterator.next();
// 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.
tip
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).
Example:
var ad = adsIterator.next();
ad.pause();
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 =
campaignIterator.next();
var adGroupBuilder =
campaign.newAdGroupBuilder();
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 =
adGroupBuilder
.build()
.getResult();
tip
pro tip
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
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.
- 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.
- 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.
- 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:
- 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)
- 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.
- 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.
- 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.
- 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.
- 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.
- View common script examples by clicking the “Show Examples” button while you’re editing. Copy the example and edit from there!
- Keep your naming process consistent throughout the script to avoid confusion.
- 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.
- Always check the comments/feedback section for any potential bugs/fixes if you decide to use a script posted online.
- 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.
- Specify the date range. If the date range is input incorrectly, the script will stop running.
- Specify the campaign. Ensure you are pulling the correct data into your report
- 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
- Missing semicolons. These are sometimes mistaken with periods; ensure all semicolons are noted to allow the script to know where the expression ends.
- 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.com, Google 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!