Scripts Save Lives
I love algorithms and you should too. They provide simple consistency to life like no calendar, routine or habit ever could. They do exactly what you tell them to do and they do it fast, and most beautiful of all, they make life automatic. (sigh of contentment)
I also love javascript but sadly, there are not a lot of places where javascript and algorithms intersect. Scripts for Adwords is one of those happy unions and this delicious union of medium and method has a little cherry on top called automation. Ain’t it sweet!
Adwords Scripts are great for automating reporting, pulling info from other API’s into Adwords and routine account maintenance. The idea for this one was brought up to me by my Google Adwords Rep. Scott, who it turns out, is rad. He called me up one day mentioning how we could optimize one of my accounts. (To be read: “make more money selling ads for Google.”) He suggested that we add mobile preferred ads to all my adgroups with a click-to-call extension, suggesting that this could potentially increase conversion rates from mobile users who are better at calling then poking their screen.
“Lets try it!” I said then thought, “How can I automate this?”
As it turns out, its not fully automatable, as the Adwords Script API does not allow for extensions to be added to ads in the ad creation process. But we can automate our work most of the way there:
How it Works
This script mirrors the process that I went through with my Adwords rep:
- Select the ad with highest click through rate in its adgroup
- Copy the headline and URL’s for the selected ad
- Make a copy with a historically successful call-to-action
- Make a copy with a mobile optimized call-to-action
- Set this ad to be mobile-preferred.
But instead of doing this one by one or in a spreadsheet, the script iterates through all adgroups in a the account, and makes the changes with one click. (Now you get why I love algorithms?)
There is one last manual step though. As I mentioned before, Scripts won’t allow for adding extensions or labels in the ad creation process. This means that you will have to go into the Adwords interface, create your click-to-call ad extension and apply it to all your ad groups. To be safe make sure that the call-to-click extension applies only to mobile ad extensions.
So here is the script the script can also be found on my github.
function main() { //set the following variables to customize the script to your account var IMPRESSIONS_THRESHOLD = 100; // min. impressions an ad needs to have to be considered var DATE_RANGE = "LAST_30_DAYS"; // time frame for impression threshold var ADGROUP_NAME_CONTAINS = 'something'; // word or phrase that eligible adgroup name must contain var DESC_LINE_1 = "Free Shipping and Free Returns!"; // description line 1 (end with punctuation) var CTA_CONTROL = "Shop Latest Cool Styles Today"; // a historically succesful CTA for line 2 var CTA_MOBILE = "Call Now To Place Your Order"; // new mobilized CTA to test for line 2 // select adgroups that meet criteria defined above var adGroupSelector = AdWordsApp .adGroups() .withCondition("Status = ENABLED") .withCondition("CampaignName CONTAINS_IGNORE_CASE " + "'" + ADGROUP_NAME_CONTAINS + "'") var adGroupIterator = adGroupSelector.get(); // iterate through all selected adgroups while (adGroupIterator.hasNext()) { var adGroup = adGroupIterator.next(); var headline; var displayURL; var destURL; var optArgs = { isMobilePreferred: true }; // select enabled ads that meet predifined criteria // ad with best ctr for each group will be copied var adSelector = adGroup.ads() .forDateRange(DATE_RANGE) .withCondition("Status = ENABLED") .withCondition("Impressions > " + IMPRESSIONS_THRESHOLD) .orderBy("Ctr DESC"); // this iterator does not really iterate, instead // it orders by CTR and selects ad with highest CTR var adIterator = adSelector.get(); while (adIterator.hasNext()) { var ad = adIterator.next(); var stats= ad.getStatsFor(DATE_RANGE); // headline and URLS are selected from ad headline = ad.getHeadline(); displayUrl = ad.getDisplayUrl(); destinationUrl = ad.getDestinationUrl(); Logger.log(headline +": " + stats.getCtr()) break; } // and are copied along with pre-defined description line // to create to versions of the mobile-prefered ad adGroup.createTextAd( headline, DESC_LINE_1, CTA_CONTROL, displayUrl, destinationUrl, optArgs ) adGroup.createTextAd( headline, DESC_LINE_1, CTA_MOBILE, displayUrl, destinationUrl, optArgs ) } }