I recently attended a panel at SMX East where Sophie Newton from BrainLabs had a couple of great suggestions for how to use Scripts during the holidays to ensure PPC success. One of these scripts would act as an emergency stop button for an entire account.
If there is an issue with a site, pausing the right elements takes several steps:
Find what needs to be paused
Label it so it can be re-activated easily when the issue is fixed
An emergency button should work very quickly and ideally have all these steps automated to avoid making mistakes during the stressful minutes between finding an issue and dealing with it. That’s why even the steps are well defined and not particularly hard to do, a script could be desirable. Also, once the issue is resolved, it should be as easy as possible to turn everything that was disabled back on and that may also be easier to do with a script than manually.
In this post, I’ll show you the whole process of writing a script like this from scratch and my process for making the script more powerful and efficient.
Step 1: Create The Pseudocode
Regardless of whether you’ll be writing the code yourself or passing that task on to a developer, it’s a good idea to get started with pseudocode. Pseudocode is a human readable outline of the steps the script should take. This code won’t be functional, but it lays out the entire functionality.
Get all the campaigns that use the broken URL
Step through each campaign
Add a label to indicate we’ll turn it off because of a URL issue
Turn it off
If you’re working with a developer, you’ll need to get more specific than just saying ‘turn it off’ in step 4. Instead, you should say ‘pause the campaign’ to avoid any confusion between pausing, removing or other ways to turn a campaign off (like setting some weird dayparting modifiers).
We should also decide on the inputs for the script. Here let’s assume that we will provide the following inputs:
The URL associated with the broken site
The text of the label we want to attach to anything we pause
Whether we’re running the script to pause or re-enable items
On a side note, you could write the script to check for broken URLs but there are plenty of scripts that already do this, including one of ours. We want the script we’re creating here to also be useful if just the shopping cart system goes down or the payment provider is failing. In these cases, the site might load fine but purchases wouldn’t be possible so we need to be able to tell it the domain of the broken site ourselves.
Step 2: Find Matching Snippets
You can write this code from scratch, but it will be easier to see if there are some prewritten snippets of code that already do some of what you need. Google has many great small examples on their developer site or you could refer to freeadwordsscripts.com or my site optmyzr.com. For this example, you need the selector code (which finds the campaigns that are broken), the iterator code (which steps through each of the matched campaigns), and the functions that add the label and pause the campaign. These last two are built-in functions that are just one word long so those are easy but here are two snippets for the first two steps which are a few lines long each.
Snippet To Find Ads
Maybe counterintuitively, finding the campaigns requires that we use an ad or keyword selector because those are the entities that include the URL information.
I’m also putting in a variable that holds the value of the broken URL: urlToPause. This will make the script more flexible than if I hardcoded the URL.
I need the IDs of the campaigns to pause so I request that data with campaign.getId() and I’ll put only unique values into an array called campaignsToPause by using the method .push() with the value of the campaign ID.
Then I print it all out to the screen for debugging (so I can see what the script is doing).
With those changes, I get to this:
Snippet To Get Campaigns By Name
Now that I have a list of all the campaigns I need to pause, I need some code that gets these campaigns by their name or ID. Google has a nice sample that shows how to do this.
Again, there are some extra lines here that I don’t need, for example, those that print the bidding strategy of the campaign so I remove these. Here are my other tweaks:
We may need to pause several campaigns so I had stored those into the array campaignsToPause mentioned previously. I iterate through all the values of this array and run Google’s code for each one.
Rather than selecting campaigns by name I decided to select by ID. Generally selecting by ID is faster than selecting by a string like what is used for the name.
For each campaign I find, I add a label with campaign.applyLabel(labelText)
For each campaign, I pause it with campaign.pause()
Step 3: Combine The Snippets
Now we have to put the code together. Because we already wrote the pseudocode, we can just copy-and-paste the snippets we found and edited in step 2 over the pseudocode we wrote in step 1. I also add some code to the beginning where we set up the variables for the user inputs urlToPause and labelText. I also set up a new array that holds the campaigns we need to pause: campaignsToPause. The trickiest part here is to make sure you balance your parentheses and brackets inside the function main(). If they’re not balanced, the code won’t even preview. Fear not though, the AdWords built-in script editor does a great job telling you if there is an issue on a particular line of your code. Here’s what I’m now left with:
These 47 lines of mostly copied-and-pasted code will pause campaigns in my account that direct users to a broken site.
Step 4: Make It Work Better And On Really Big Accounts
You may have noticed that our code so far assumes we’re setting final URLs at the ad level. If we have keyword level URLs, this script will not work correctly.
Also note that the code that we have now will work so long as the script doesn’t time out (Google has a 30-minute execution limit for each script execution) and so long as you’re not interacting with more than 250,000 entities (this is also a Google imposed limit). Because we are working with just campaigns in this script, it won’t hit the entity limit because that’s much higher than the Adwords limit for maximum campaigns in an account which is currently 10,000.
We can fix the keyword issue and at the same time make this script better by making it pause ad groups rather than campaigns and by using a report to get the ad groups that should be paused. That way it can deal with accounts that include several sites in each campaign. Because the ad group limits for accounts are much higher than campaign limits, adding a level of efficiency becomes much more important. Rather than using a selector to find the ad groups we need, let’s use a report. By using a report, each ad group we find won’t count against our 250,000 entity limit and results will come back much faster.
Snippet To Run An AdWords Report
We go back to looking for a snippet of code to help us use a report to find ad groups that use a broken URL. You’ll probably look at the AD_PERFORMANCE_REPORT first only to find it doesn’t include final URL data. Luckily there is a FINAL_URL_REPORT that seems to have the data we need and we’re lucky that it contains the data for ads and keywords in a single report so our keyword issue will automatically be resolved if we can get this code to work.
I basically took the first piece of code I had written in step 2 and added in the reporting code to get to the following. I’ll show you the old and new code next to each other.
As you can tell, I also changed every reference to ‘campaign’ to ‘adGroup’ with a simple find and replace while preserving the correct casing (camel case for example).
Step 5: Add The Function To Turn Everything Back On
When the site is fixed, we’ll want to turn it back on quickly and we’ll do that by finding all paused items that include the label we set when we turned it off and then re-enabling each of these. I’m using a report to find all the ad groups that have the label and the code should start to look familiar by now:
Here the only tricky part is that selecting ad groups by label requires me to know the label’s ID rather than its name. The first line of code deals with translating the name into an ID that I can then use in the reporting call.
Step 6: Put It All Together
Because we’d like to have a single script that handles both the pausing and re-activating we’ll need to add a setting to the script that indicates what we want it to do: pause or re-activate. For this, we add a variable called ‘mode’ with a possible value of either ‘pause’ or ‘resume’. Then we use an if-else loop to do different things depending on the setting. You can get the final resulting code from my BitBucket repository for your own use.
You can copy and paste this into your accounts and use it. Always be sure to run the script in preview mode first and I recommend always backing up your account in Editor when you make large scale changes like this.
I hope that by taking you through the process of creating a simple yet useful script, and the steps I went through to make it work better on large accounts gives you a better sense of what it takes to create your own script. Notice that I didn’t write very much code myself, I mostly found useful snippets, put them in the right order and changed some of the operations done on the data. I hope this inspires you to try it for yourself.
If you want to use this script at the MCC level, or have us at Optmyzr worry about making sure the script continues to work as Google makes changes to Scripts and the API, or if you simply don’t want to deal with code, be sure to check out our award winning PPC management tools where we’ve turned this into an Enhanced Script for AdWords.