Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // REMOVE UNDERPERFORMING TEXT ADS
- // -------------------------------------------------
- // Script created by Frederick Vallaeys
- // Optmyzr - http://www.optmyzr.com
- // Copyright 2012-2013 - Optmyzr
- //
- // WARNING: Test all scripts in preview mode before running them!
- // This script can make changes to your account. There is no 'undo'
- // feature so make a backup of your account in AdWords Editor before
- // running this script.
- function main() {
- // SETTINGS - Change these if needed
- var time = "LAST_30_DAYS"; //TODAY, YESTERDAY, LAST_7_DAYS, THIS_WEEK_SUN_TODAY, LAST_WEEK, LAST_14_DAYS, LAST_30_DAYS, LAST_BUSINESS_WEEK, LAST_WEEK_SUN_SAT, THIS_MONTH, LAST_MONTH, ALL_TIME
- var campaignSelectorStatement = "Name CONTAINS_IGNORE_CASE ''"
- var minAdsToKeepPerAdGroup = 2;
- var suggestMode = 1;
- var deleteAds = 0;
- var pauseAds = 1;
- // END SETTINGS
- // Script variables
- var minImpressionsBeforeAdCanBeDeleted = 25;
- var minImpressionsForAdGroupBeforeOptimization = 100;
- var percentImpressionVariationAllowedBeforeDeleting = .1;
- var percentCTRVariationAllowedBeforeDeleting = .1;
- var percentConversionVariationAllowedBeforeDeleting = .1;
- Logger.log("Remove Underperforming Ads");
- Logger.log("-------------------------------");
- Logger.log("This script's copyright belongs to Optmyzr and Frederick Vallaeys. The code may not be copied, modified or distributed without permission.")
- Logger.log("");
- Logger.log("Purpose");
- Logger.log("-------");
- Logger.log("This script helps you identify and remove underperforming text ads in your AdWords account.");
- Logger.log("");
- Logger.log("Settings:");
- Logger.log("--------");
- Logger.log("- date range: " + time);
- Logger.log("- evaluate all campaigns that match the selector '" + campaignSelectorStatement + "'");
- Logger.log("- keep at least " + minAdsToKeepPerAdGroup + " ad variations in each ad group");
- Logger.log("- evaluate only ad groups with at least " + minImpressionsForAdGroupBeforeOptimization + " impressions");
- Logger.log("- do not remove ads with fewer than " + minImpressionsBeforeAdCanBeDeleted + " impressions");
- Logger.log("- remove ads that underdeliver impressions by more than " + percentImpressionVariationAllowedBeforeDeleting*100 + "%");
- Logger.log("- save underperforming ads if their CTR outperforms their impressions by at least " + percentCTRVariationAllowedBeforeDeleting*100 + "%");
- Logger.log("- save underperforming ads if their conversions outperform their impressions by at least " + percentConversionVariationAllowedBeforeDeleting*100 + "%");
- Logger.log("- test mode: " + suggestMode);
- Logger.log("- delete ads: "+ deleteAds);
- Logger.log("- pause ads: " + pauseAds);
- Logger.log("");
- Logger.log("");
- // Get an iterator over campaigns so we can total all the impressions
- var campaignIterator = AdWordsApp.campaigns()
- .forDateRange(time)
- .withCondition("Status = ENABLED")
- .withCondition(campaignSelectorStatement)
- .orderBy("Impressions DESC")
- .withLimit(10)
- .get();
- var adArray = new Array();
- var deletionAllowed = 1;
- var totalCostSaved = 0;
- var totalClicksGained = 0;
- while(campaignIterator.hasNext()) {
- var campaign = campaignIterator.next();
- var campaignName = campaign.getName();
- Logger.log("Campaign: " + campaignName);
- var campaignAdGroupIterator = campaign.adGroups()
- .forDateRange(time)
- .withCondition("Status = ENABLED")
- .withCondition("Impressions >= " + minImpressionsForAdGroupBeforeOptimization)
- .orderBy("Impressions DESC")
- .get();
- while(campaignAdGroupIterator.hasNext()) {
- var adGroup = campaignAdGroupIterator.next();
- var adGroupName = adGroup.getName();
- var adGroupStats = adGroup.getStatsFor(time);
- var adGroupImpressions = adGroupStats.getImpressions();
- var adGroupClicks = adGroupStats.getClicks();
- var adGroupConversions = adGroupStats.getConversions();
- var adGroupCtr = adGroupStats.getCtr();
- var adGroupConversionRate = adGroupStats.getConversionRate();
- var adGroupAvgCpc = adGroupStats.getAverageCpc();
- var adGroupAdIterator = adGroup.ads()
- .withCondition("Status = ENABLED")
- .forDateRange(time)
- .orderBy("Impressions DESC")
- .get();
- Logger.log(" Ad Group Name: " + adGroupName);
- Logger.log(" impressions: " + adGroupImpressions);
- var textAdImpressions = 0;
- var textAdClicks = 0;
- var textAdConversions = 0;
- var textAdCount = 0;
- var templateAdImpressions = 0;
- while (adGroupAdIterator.hasNext()) {
- var ad = adGroupAdIterator.next();
- var adHeadline = ad.getHeadline();
- var adLine1 = ad.getDescription1();
- var adLine2 = ad.getDescription2();
- var destinationUrl = ad.getDestinationUrl();
- var displayUrl = ad.getDisplayUrl();
- var adType = ad.getType();
- var adStats = ad.getStatsFor(time);
- var adImpressions = adStats.getImpressions();
- var adClicks = adStats.getClicks();
- var adAvgCpc = adStats.getAverageCpc();
- var adConversions = adStats.getConversions();
- if(adType == "TEXT_AD") {
- textAdImpressions+= adImpressions;
- textAdClicks += adClicks;
- textAdConversions += adConversions;
- textAdCount++;
- adArray.push(new adUnit(campaignName, adGroupName, adType, adHeadline, adLine1, adLine2, displayUrl, destinationUrl, adImpressions, adClicks, adConversions, adAvgCpc, adGroupCtr, adGroupConversionRate, adGroupAvgCpc));
- }
- if(adType == "TEMPLATE_AD") {
- templateAdImpressions+= adImpressions;
- }
- }
- Logger.log(" contains " + textAdCount + " text ads");
- Logger.log("");
- if(textAdCount > minAdsToKeepPerAdGroup && adGroupImpressions >= minImpressionsForAdGroupBeforeOptimization)
- {
- // Sort the ads by impressions from high to low
- adArray.sort(function(a,b) {
- return a.impressions-b.impressions
- });
- var deletionCount = 0;
- // Process the ad group's ads now that we have all the stats
- for (var i = 0; i < adArray.length; i++) {
- var ad = adArray[i];
- var headline = ad.headline;
- var line1 = ad.line1;
- var line2 = ad.line2;
- var displayUrl = ad.displayUrl;
- var destinationUrl = ad.destinationUrl;
- var campaignName = ad.campaignName;
- var adGroupName = ad.adGroupName;
- var impressions = ad.impressions;
- var clicks = ad.clicks;
- var ctr = 100 * clicks/impressions;
- var cpc = ad.cpc;
- var conversions = ad.conversions;
- var type = ad.type;
- var adGroupCtr = 100 * ad.adGroupCtr;
- var adGroupConversionRate = ad.adGroupConversionRate;
- var adGroupAvgCpc = ad.adGroupAvgCpc;
- var minImpPercent = (100 / textAdCount) * (1-percentImpressionVariationAllowedBeforeDeleting);
- if(type == "TEXT_AD") {
- var percentImpressions = impressions / textAdImpressions * 100;
- var percentClicks = clicks / textAdClicks * 100;
- var percentConversions = conversions / textAdConversions * 100;
- Logger.log(" | " + headline);
- Logger.log(" | " + line1);
- Logger.log(" | " + line2);
- Logger.log(" | " + displayUrl);
- Logger.log(" ----------------------------------------------");
- Logger.log(" imp:" + percentImpressions.toFixed(2) + "% | clicks: " + percentClicks.toFixed(2) + "% | conv: " + percentConversions.toFixed(2) + "%");
- var relativeConversions = (1 - percentConversionVariationAllowedBeforeDeleting) * percentConversions;
- var relativeCTR = (1 - percentCTRVariationAllowedBeforeDeleting) * percentClicks;
- if(deletionAllowed) {
- if(percentImpressions < minImpPercent)
- {
- if(textAdConversions > 0)
- {
- if(relativeConversions > percentImpressions) {
- Logger.log(" <-- saved by conversions");
- } else {
- deleteAd(campaignName, adGroupName, headline, line1, line2, displayUrl, destinationUrl, suggestMode, pauseAds, deleteAds);
- deletionCount++;
- var clicksGained = (adGroupCtr - ctr) / 100 * impressions;
- totalClicksGained += clicksGained;
- var costSaved = (cpc - adGroupAvgCpc) * clicks;
- totalCostSaved += costSaved;
- if(clicksGained > 0) {
- Logger.log("Removing this ad may get you " + clicksGained.toFixed(0) + " additional clicks over 30 days.");
- }
- if(costSaved > 0) {
- Logger.log("Removing this ad may save you $" + costSaved.toFixed(2) + " over 30 days.");
- }
- }
- } else {
- if(relativeCTR > percentImpressions) {
- Logger.log(" <-- saved by CTR");
- } else {
- deleteAd(campaignName, adGroupName, headline, line1, line2, displayUrl, destinationUrl, suggestMode, pauseAds, deleteAds);
- deletionCount++;
- var clicksGained = (adGroupCtr - ctr) / 100 * impressions;
- totalClicksGained += clicksGained;
- var costSaved = (cpc - adGroupAvgCpc) * clicks;
- totalCostSaved += costSaved;
- if(clicksGained > 0) {
- Logger.log("Removing this ad may get you " + clicksGained.toFixed(0) + " additional clicks over 30 days.");
- }
- if(costSaved > 0) {
- Logger.log("Removing this ad may save you $" + costSaved.toFixed(2) + " over 30 days.");
- }
- }
- }
- }
- }
- }
- if(type == "TEMPLATE_AD") {
- // Not in use because we can't see the ad sizes in the script so we can't compare apples to apples
- //var percentImpressions = impressions / templateAdImpressions * 100;
- }
- Logger.log(" ");
- if((textAdCount - deletionCount) <= minAdsToKeepPerAdGroup) {
- //Logger.log("Deletion no longer allowed, min ad group size reached");
- deletionAllowed = 0;
- }
- }
- } else {
- Logger.log(" The ad group above did not qualify for optimization - check your settings to change this");
- Logger.log("");
- }
- var adArray = new Array();
- var adStatsArray = new Array();
- var textAdImpressions = 0;
- var textAdClicks = 0;
- var textAdConversions = 0;
- var templateAdImpressions = 0;
- var thisAGAdCount = 0;
- var textAdCount = 0;
- var deletionCount = 0;
- var deletionAllowed = 1;
- }
- }
- Logger.log("This entire optimization may get you " + totalClicksGained.toFixed(0) + " additional clicks ");
- Logger.log("and save you $" + totalCostSaved.toFixed(2) + " over 30 days.");
- }
- function adUnit(campaignName, adGroupName, type, headline, line1, line2, displayUrl, destinationUrl, impressions, clicks, conversions, cpc, adGroupCtr, adGroupConversionRate, adGroupAvgCpc)
- {
- this.campaignName = campaignName;
- this.adGroupName = adGroupName;
- this.type = type;
- this.headline = headline;
- this.line1 = line1;
- this.line2 = line2;
- this.displayUrl = displayUrl;
- this.destinationUrl = destinationUrl;
- this.impressions = impressions;
- this.clicks = clicks;
- this.conversions = conversions;
- this.cpc = cpc;
- this.adGroupCtr = adGroupCtr;
- this.adGroupConversionRate = adGroupConversionRate;
- this.adGroupAvgCpc = adGroupAvgCpc;
- }
- function deleteAd(campaignName, adGroupName, headline, line1, line2, displayUrl, destinationUrl, suggestMode, pauseAd, deleteAd)
- {
- var adToProcessIterator = AdWordsApp.ads()
- .withCondition("Headline = \"" + headline.replace(/[\[\]\"]/g, "") + "\"")
- .withCondition("Description1 = \"" + line1.replace(/[\[\]\"]/g, "") + "\"")
- .withCondition("Description2 = \"" + line2.replace(/[\[\]\"]/g, "") + "\"")
- .withCondition("DisplayUrl = '" + displayUrl + "'")
- .withCondition("DestinationUrl = '" + destinationUrl + "'")
- .withCondition("AdGroupName = '" + adGroupName + "'")
- .withCondition("CampaignName = '" + campaignName + "'")
- .get();
- while(adToProcessIterator.hasNext())
- {
- var adToProcess = adToProcessIterator.next();
- var headline = adToProcess.getHeadline();
- var line1 = adToProcess.getDescription1();
- var line2 = adToProcess.getDescription2();
- if(pauseAd) {
- if(!suggestMode) {
- adToProcess.pause();
- Logger.log(" >> Ad paused <<");
- } else {
- Logger.log(" >> Test mode: this ad would have been paused otherwise <<");
- }
- } else if(deleteAd) {
- if(!suggestMode) {
- adToProcess.remove();
- Logger.log(" >> Ad deleted <<");
- } else {
- Logger.log(" >> Test mode: this ad would have been deleted otherwise <<");
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement