Snippets

Frederick Vallaeys Bulk Create Ads

Created by Frederick Vallaeys

File Optmyzr Script.js Added

  • Ignore whitespace
  • Hide word diff
+var DEBUG = 1;
+var currentSetting = new Object();
+  
+function main(){
+  currentSetting.enabledCampaignsOnly = 1;
+  currentSetting.enabledAdGroupsOnly = 1;
+  var adLabel = "";
+  currentSetting.calculation1 = "?Ctr * ?ConversionRate";
+  currentSetting.keepHighestOrLowest = "highest";
+  currentSetting.sortBy = "Ctr"; //"clickShare, "impressionShare", "conversionShare", "convertedClicksShare";
+  currentSetting.showAllAds = 1;
+  currentSetting.devicePreference = "notMobilePreferred"; //"all", "mobilePreferred"
+  currentSetting.numAdsToKeep = 3;
+  currentSetting.optimizationMethod = "add n"; //"at least n", "add n";
+  currentSetting.time = "LAST_30_DAYS";
+  currentSetting.email = "example@example.com";
+  accountManagers = "example@example.com,example@example.com";
+  var campaignNameContains = "";
+  var campaignLabel = "";
+  currentSetting.adImpressionThreshold = 100;
+  currentSetting.showAdLabels = 0;
+  currentSetting.showAdGroupLabels = 0;
+  
+  
+  if(!currentSetting.keepHighestOrLowest) currentSetting.keepHighestOrLowest = "Highest";
+  if(!currentSetting.sortBy) currentSetting.sortBy = "Ctr";
+  currentSetting.sortBy = currentSetting.sortBy.replace(/ /g, '');
+  if(DEBUG==1) Logger.log("currentSetting.sortBy: " + currentSetting.sortBy);
+  if(!campaignNameContains) var campaignNameContains = "";
+  if(!campaignLabel) var campaignLabel = "";
+  if(!adLabel) var adLabel = "";
+  if(!currentSetting.pausedOrDeleted) currentSetting.pausedOrDeleted = "Pause";
+  if(!currentSetting.adImpressionThreshold) currentSetting.adImpressionThreshold = 0;
+  if(currentSetting.pausedOrDeleted == "Pause") {
+    currentSetting.pausedOrDeleted = "Paused";
+  } else {
+    currentSetting.pausedOrDeleted = "Removed";
+  }
+  
+  if(currentSetting.optimizationMethod.toLowerCase().indexOf("add n") != -1) {
+    currentSetting.optMode = "addN";
+  } else if(currentSetting.optimizationMethod.toLowerCase().indexOf("at least n") != -1) {
+    currentSetting.optMode = "expandToN";
+  }
+  
+  if(DEBUG==1) Logger.log("currentSetting.showAllAds: " + currentSetting.showAllAds);
+  
+  
+  
+  var accountName = AdWordsApp.currentAccount().getName();
+  
+  if(campaignLabel) {
+    currentSetting.matchedCampaigns = getMatchingCampaignIds(campaignLabel);
+  }
+  
+  
+  if(adLabel) currentSetting.matchedAds = getMatchingAdIds(adLabel, campaignLabel);
+  
+  var campaignNameCaseSensitive = 0;
+  var campaignNameExactMatch = 0;
+  if(campaignNameContains) currentSetting.campaignNameSelector = getCampaignsByName(campaignNameContains, campaignNameCaseSensitive, campaignNameExactMatch);
+  
+  
+  // --- SET UP SPREADSHEET -----
+  
+  // Construct report name
+  var reportDate = new Date();
+  spreadsheetName = "Optmyzr Bulk Ads" + " - " + accountName;
+  
+  var spreadsheet = SpreadsheetApp.create(spreadsheetName);
+  var spreadsheetUrl = spreadsheet.getUrl();
+  var allSheets = spreadsheet.getSheets(); 
+  
+  // remove
+  for(var i=1,len=allSheets.length;i<len;i++){
+    spreadsheet.deleteSheet(allSheets[i]);
+  }
+  
+  // create
+  allSheets[0].setName(currentSetting.sheetName);
+
+  var spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
+  var isSpreadsheetNew = 1;
+  
+  
+  // ADD ACCOUNT MANAGERS
+  if(accountManagers && accountManagers!=""){
+    var accountManagersArray = accountManagers.replace(/\s/g, "").split(",");
+    spreadsheet.addEditors(accountManagersArray);
+  }
+  
+  currentSetting.analysisSheet = spreadsheet.getSheetByName(currentSetting.sheetName);
+  currentSetting.analysisSheet.appendRow(["Action", "Campaign", "Ad Group", "Ad Type", "Ad", "Headline Length", "Description Line 1", "Line 1 Length", "Description Line 2", "Line 2 Length", "Display URL", "Display URL Length", "Final URL", "Mobile Final URL", "Tracking Template", "Custom Parameter", "Clicks", "ClickShare", "Impressions", "ImpressionShare", "Ctr", "AveragePosition", "Cost", "AverageCpc", "ConversionValue", "ROAS", "Conversions", "ConversionShare", "ConversionRate", "CostPerConversion", "ConvertedClicks", "ConvertedClickShare", "clickConversionRate", "CostPerConvertedClick", "calculation1", "devicePreference", "adLabel", "adGroupLabel", "adId", "adGroupId"]);
+  currentSetting.analysisSheet.setFrozenRows(1);
+  
+  
+  buildAccountMap(campaignLabel, adLabel, campaignNameContains, currentSetting.time);
+  addCalculatedMetrics();
+  
+  sortAds();
+  writeToSheet();
+  addCharacterCountColumns();
+  currentSetting.finished = 1;
+  addStyleToSheet(currentSetting.analysisSheet);
+  
+  var notes = "Bulk Ad Sheet: <a href=\""+spreadsheetUrl+"\" target=\"_blank\">link</a>";
+  
+  if(currentSetting.email) {
+    var subject = "New Ad Bulksheet Is Ready";
+    var body = "Your spreadsheet to bulk create new ads is ready: <a href=\""+spreadsheet.getUrl()+"\" target=\"_blank\">link</a><br/><br/>" + "Manage the Optmyzr Enhanced Script that created this report: https://tools.optmyzr.com/enhancedscript_settings/scriptSettings/61";
+    sendEmailNotifications(currentSetting.email, subject, body);
+  }
+    
+  return(notes);
+  
+}
+ 
+  function getMatchingAdIds(label, campaignLabel)
+  {
+    var matchedAds = new Object();
+    matchedAds.ids = new Array();
+    
+    if(!campaignLabel) {
+      var adIterator = AdWordsApp.ads()
+      .withCondition("LabelNames CONTAINS_ANY ['" + label + "']")
+      .get();
+    } else {
+      var adIterator = AdWordsApp.ads()
+      .withCondition("LabelNames CONTAINS_ANY ['" + label + "']")
+      .withCondition(matchedCampaigns.selectorStringForScripts)
+      .get();
+    }
+    while(adIterator.hasNext()) {
+      var ad = adIterator.next();
+      var adId = ad.getId();
+      matchedAds.ids.push(adId);
+    } 
+    matchedAds.selectorStringForReports = "AdId IN [" + matchedAds.ids + "]";
+    matchedAds.selectorStringForAdPerformanceReports = "Id IN [" + matchedAds.ids + "]";
+    return(matchedAds);
+  }
+  
+
+
+function buildAccountMap(campaignLabel, adLabel, campaignNameContains, time) {
+  currentSetting.accountMap = new Object();
+  currentSetting.accountMap.campaigns = new Array();
+  
+  var cols = ['Headline', 
+              'Description1', 
+              'Description2', 
+              'DisplayUrl', 
+              'CreativeFinalUrls', 
+              'CreativeFinalMobileUrls',
+              'CreativeTrackingUrlTemplate',
+              'CreativeUrlCustomParameters',
+              'CampaignName', 
+              'CampaignId', 
+              'AdGroupName', 
+              'AdGroupId', 
+              'Id', 
+              'AdType', 
+              'DevicePreference', 
+              'Clicks', 
+              'Impressions', 
+              'Cost', 
+              'Conversions', 
+              'ConvertedClicks',
+              'ConversionValue', 
+              'AveragePosition', 
+              'Ctr', 
+              'ConversionRate',
+              'ClickConversionRate',
+              'AverageCpc'];
+  
+  if(currentSetting.devicePreference.toLowerCase() == "mobile preferred") {
+    var query = ['SELECT ', 
+                 cols.join(','),
+                 'FROM AD_PERFORMANCE_REPORT',
+                 'WHERE DevicePreference = 30001',
+                 'AND Status = ENABLED'];
+  } else if (currentSetting.devicePreference.toLowerCase() == "not mobile preferred") {
+    var query = ['SELECT ', 
+                 cols.join(','),
+                 'FROM AD_PERFORMANCE_REPORT',
+                 'WHERE DevicePreference != 30001',
+                 'AND Status = ENABLED'];
+  } else {
+    var query = ['SELECT ', 
+                 cols.join(','),
+                 'FROM AD_PERFORMANCE_REPORT',
+                 'WHERE Status = ENABLED'];
+  }
+  if(campaignLabel) query.push('AND', currentSetting.matchedCampaigns.selectorStringForReports);
+  if(adLabel) query.push('AND', currentSetting.matchedAds.selectorStringForAdPerformanceReports);
+  if(campaignNameContains) query.push('AND', currentSetting.campaignNameSelector.forReports);
+  if(currentSetting.enabledCampaignsOnly) query.push('AND', 'CampaignStatus = ENABLED');
+  if(currentSetting.enabledAdGroupsOnly) query.push('AND', 'AdGroupStatus = ENABLED');
+  query.push('DURING', time);
+  var query = query.join(' ');
+  if(DEBUG == 1) Logger.log("query: " + query);
+  var report = AdWordsApp.report(query);
+  var rows = report.rows();
+  
+  while(rows.hasNext()) {
+    var row = rows.next();
+    for(var key in row) {
+      var value = row[key];
+      currentSetting[key] = value;
+    }
+    
+    if(currentSetting.DevicePreference == "--") {
+      currentSetting.DevicePreference = "All";
+    } else {
+      currentSetting.DevicePreference = "Mobile";
+    }
+    
+    if(!currentSetting.accountMap.campaigns[currentSetting.CampaignName]) {
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName] = new Object();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups = new Array();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName] = new Object();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads = new Array();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numMobilePreferredTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numNonMobilePreferredTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].sortedAdList = new Array();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id] = new Object();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].adGroupId = currentSetting.AdGroupId;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Impressions = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Clicks = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Conversions = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ConvertedClicks = 0;
+    } else if (!currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName]) {
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName] = new Object();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads = new Array();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numMobilePreferredTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numNonMobilePreferredTextAds = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].sortedAdList = new Array();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id] = new Object();
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].adGroupId = currentSetting.AdGroupId;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Impressions = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Clicks = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Conversions = 0;
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ConvertedClicks = 0;
+    } else if (!currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id]) {
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id] = new Object();
+    }
+    //Logger.log(currentSetting.AdType);
+    if(currentSetting.AdType == "Text ad") {
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numTextAds++;
+      if(currentSetting.DevicePreference == "mobile preferred") {
+        currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numMobilePreferredTextAds++;
+      } else {
+        currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].numNonMobilePreferredTextAds++;
+      }
+    }
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].headline = currentSetting.Headline;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].description1 = currentSetting.Description1;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].description2 = currentSetting.Description2;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].displayUrl = currentSetting.DisplayUrl;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].finalUrls = currentSetting.CreativeFinalUrls;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].finalMobileUrls = currentSetting.CreativeFinalMobileUrls;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].creativeTrackingUrlTemplate = currentSetting.CreativeTrackingUrlTemplate;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].creativeUrlCustomParameters = currentSetting.CreativeUrlCustomParameters;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].Clicks = parseInt(currentSetting.Clicks);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].Impressions = parseInt(currentSetting.Impressions);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].Cost = getFloat(currentSetting.Cost);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].Conversions = getFloat(currentSetting.Conversions);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].ConvertedClicks = parseInt(currentSetting.ConvertedClicks);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].ConversionValue = getFloat(currentSetting.ConversionValue);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].ConversionRate = getFloat(currentSetting.ConversionRate);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].ClickConversionRate = getFloat(currentSetting.ClickConversionRate);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].AverageCpc = getFloat(currentSetting.AverageCpc);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].Ctr = getFloat(currentSetting.Ctr);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].AveragePosition = getFloat(currentSetting.AveragePosition);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].devicePreference = currentSetting.DevicePreference;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].adType = currentSetting.AdType;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].CostPerConversion = currentSetting.Cost / currentSetting.Conversions;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].CostPerConvertedClick = currentSetting.Cost / currentSetting.convertedClicks;
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].adId = currentSetting.Id;
+    //Logger.log("ROAS: " + currentSetting.ConversionValue / currentSetting.Cost);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].ROAS = getFloat(currentSetting.ConversionValue / currentSetting.Cost);
+    
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Impressions += parseInt(currentSetting.Impressions);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Clicks += parseInt(currentSetting.Clicks);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].Conversions += getFloat(currentSetting.Conversions);
+    currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ConvertedClicks += parseInt(currentSetting.ConvertedClicks);;
+    
+    
+    // Calculated
+    if(currentSetting.calculation1){
+      var calculation = currentSetting.calculation1;
+      if(DEBUG==1) Logger.log("calculation: " + calculation);
+      var fullCalculation = calculation.replace(/\?/g, "currentSetting.");
+      if(DEBUG==1) Logger.log("fullCalculation: " + fullCalculation);
+      var output = eval(fullCalculation);
+      //var output = currentSetting.AveragePosition * currentSetting.AverageCpc * (1/currentSetting.Ctr) * (1/currentSetting.ConversionRate);
+      //Logger.log(output);
+      
+      currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].calculation1 = output;
+      
+    }
+    //Logger.log("Clicks: " + currentSetting.accountMap.campaigns[currentSetting.CampaignName].adGroups[currentSetting.AdGroupName].ads[currentSetting.Id].clicks);
+    
+  }
+} // END buildAccountMap
+
+function writeToSheet(reportDates) {
+  
+  //var label = currentSetting.label;
+  for(var campaignName in currentSetting.accountMap.campaigns) {
+    for (var adGroupName in currentSetting.accountMap.campaigns[campaignName].adGroups) {
+      var adGroupId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].adGroupId;
+      var adGroupLabel = "";
+      if(currentSetting.showAdGroupLabels) var adGroupLabel = getLabelsForAdGroup(adGroupId);
+      
+      var numTextAdsInAdGroup = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].numTextAds;
+      if(DEBUG==1) Logger.log("");
+      if(DEBUG==1) Logger.log(campaignName + " > " + adGroupName + " contains " + numTextAdsInAdGroup + " text ads (" + currentSetting.devicePreference + ")");
+      if(DEBUG==1) Logger.log("-----------------------");
+        
+      if(currentSetting.optMode == "addN" || currentSetting.optMode == "expandToN") {
+        if(currentSetting.optMode == "expandToN") {
+          var numAdsToAdd = currentSetting.numAdsToKeep - numTextAdsInAdGroup;
+        } else if(currentSetting.optMode == "addN") {
+          var numAdsToAdd = currentSetting.numAdsToKeep;
+        }
+        
+        if(numAdsToAdd > 0) {
+          if(currentSetting.optMode == "expandToN") {
+            var numAdsToAdd = currentSetting.numAdsToKeep - numTextAdsInAdGroup;
+          } else if(currentSetting.optMode == "addN") {
+            var numAdsToAdd = currentSetting.numAdsToKeep;
+          }
+          if(DEBUG==1) Logger.log("numAdsToAdd: " + numAdsToAdd);
+          var recommendedStatus = "add";
+          
+          for(var counter = 0; counter < currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.length; counter++) {
+            if(currentSetting.keepHighestOrLowest.toLowerCase().indexOf("lowest") != -1) {
+              var length = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.length - 1 - counter;
+              var adId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList[length];
+            } else {
+              var adId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList[counter];
+            }
+            if(currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId].Impressions >= currentSetting.adImpressionThreshold) {
+              break;
+            }
+            
+            // didn't find ad with enough data, so take the best alternative
+            if(counter == currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.length + 1) {
+              if(currentSetting.keepHighestOrLowest.toLowerCase().indexOf("lowest") != -1) {
+                var length = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.length - 1;
+                var adId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList[length];
+              } else {
+                var adId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList[0];
+              }
+            }
+          }
+          
+          var thisAd = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId];
+          
+          var headline = thisAd.headline;
+          var description1 = thisAd.description1;
+          var description2 = thisAd.description2;
+          var finalUrls = thisAd.finalUrls;
+          var finalMobileUrls = thisAd.finalMobileUrls;
+          var displayUrl = thisAd.displayUrl;
+          var clicks = thisAd.Clicks;
+          var impressions = thisAd.Impressions;
+          var cost = thisAd.Cost;
+          var clicks = thisAd.Clicks;
+          var conversions = thisAd.Conversions;
+          var convertedClicks = thisAd.ConvertedClicks;
+          var clickConversionRate = thisAd.ClickConversionRate/100;
+          var conversionValue = thisAd.ConversionValue;
+          var ctr = thisAd.Ctr/100;
+          var conversionRate = thisAd.ConversionRate/100;
+          var costPerConversion = thisAd.CostPerConversion;
+          var costPerConvertedClick = thisAd.CostPerConvertedClick;
+          var calculation1 = thisAd.calculation1;
+          var clickShare = thisAd.ClickShare;
+          var impressionShare = thisAd.ImpressionShare;
+          var conversionShare = thisAd.ConversionShare;
+          var convertedClicksShare = thisAd.ConvertedClicksShare;
+          var averageCpc = thisAd.AverageCpc;
+          var averagePosition = thisAd.AveragePosition;
+          var conversionValue = thisAd.ConversionValue;
+          var roas = thisAd.ROAS;
+          var devicePreference = thisAd.devicePreference;
+          var id = thisAd.adId;
+          var adType = thisAd.adType;
+          var creativeTrackingUrlTemplate = thisAd.creativeTrackingUrlTemplate;
+          var creativeUrlCustomParameters = thisAd.creativeUrlCustomParameters;
+          if(!creativeTrackingUrlTemplate) creativeTrackingUrlTemplate = "";
+          if(!creativeUrlCustomParameters) creativeUrlCustomParameters = "";
+          if(DEBUG==1) Logger.log("Best ad's headline: " + headline + " > custom metric: " + calculation1);
+          
+          
+          var adLabel = "";
+          if(currentSetting.showAdLabels) var adLabel = getLabelsForAd(adGroupId,adId);
+          
+          for(var adsToAddCounter = 0; adsToAddCounter < numAdsToAdd; adsToAddCounter++) {
+            if(adType.toLowerCase().indexOf("text ad") != -1) {
+              currentSetting.analysisSheet.appendRow([recommendedStatus, campaignName, adGroupName, adType, headline, "", description1, "", description2, "", displayUrl, "", finalUrls, finalMobileUrls, creativeTrackingUrlTemplate, creativeUrlCustomParameters, clicks, clickShare, impressions, impressionShare, ctr, averagePosition, cost, averageCpc, conversionValue, roas, conversions, conversionShare, conversionRate, costPerConversion, convertedClicks, convertedClicksShare, clickConversionRate, costPerConvertedClick, calculation1, devicePreference, adLabel, adGroupLabel, adId, adGroupId, ""]);
+            } 
+          }
+          if(currentSetting.showAllAds) {
+            var recommendedStatus = "set";
+            
+            for(var adCounter = 0 ; adCounter < currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.length ; adCounter++) {
+              
+              var adId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList[adCounter];
+              var thisAd = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId];
+              
+              var headline = thisAd.headline;
+              var description1 = thisAd.description1;
+              var description2 = thisAd.description2;
+              var finalUrls = thisAd.finalUrls;
+              var finalMobileUrls = thisAd.finalMobileUrls;
+              var displayUrl = thisAd.displayUrl;
+              var clicks = thisAd.Clicks;
+              var impressions = thisAd.Impressions;
+              var cost = thisAd.Cost;
+              var clicks = thisAd.Clicks;
+              var conversions = thisAd.Conversions;
+              var convertedClicks = thisAd.ConvertedClicks;
+              var clickConversionRate = thisAd.ClickConversionRate/100;
+              var conversionValue = thisAd.ConversionValue;
+              var ctr = thisAd.Ctr/100;
+              var conversionRate = thisAd.ConversionRate/100;
+              var costPerConversion = thisAd.CostPerConversion;
+              var costPerConvertedClick = thisAd.CostPerConvertedClick;
+              var calculation1 = thisAd.calculation1;
+              var clickShare = thisAd.ClickShare;
+              var impressionShare = thisAd.ImpressionShare;
+              var conversionShare = thisAd.ConversionShare;
+              var convertedClicksShare = thisAd.ConvertedClicksShare;
+              var averageCpc = thisAd.AverageCpc;
+              var averagePosition = thisAd.AveragePosition;
+              var conversionValue = thisAd.ConversionValue;
+              var roas = thisAd.ROAS;
+              var devicePreference = thisAd.devicePreference;
+              var id = thisAd.adId;
+              var adType = thisAd.adType;
+              var creativeTrackingUrlTemplate = thisAd.creativeTrackingUrlTemplate;
+              var creativeUrlCustomParameters = thisAd.creativeUrlCustomParameters;
+              if(!creativeTrackingUrlTemplate) creativeTrackingUrlTemplate = "";
+              if(!creativeUrlCustomParameters) creativeUrlCustomParameters = "";
+              
+              var adLabel = "";
+              if(currentSetting.showAdLabels) var adLabel = getLabelsForAd(adGroupId,adId);
+              
+              if(adType.toLowerCase().indexOf("text ad") != -1) {
+                currentSetting.analysisSheet.appendRow([recommendedStatus, campaignName, adGroupName, adType, headline, "", description1, "", description2, "", displayUrl, "", finalUrls, finalMobileUrls, creativeTrackingUrlTemplate, creativeUrlCustomParameters, clicks, clickShare, impressions, impressionShare, ctr, averagePosition, cost, averageCpc, conversionValue, roas, conversions, conversionShare, conversionRate, costPerConversion, convertedClicks, convertedClicksShare, clickConversionRate, costPerConvertedClick, calculation1, devicePreference, adLabel, adGroupLabel, adId, adGroupId, ""]);
+              }
+            }
+          } // END if(currentSetting.showAllAds == 1)
+          
+        } // END if(numTextAdsInAdGroup < currentSetting.numAdsToKeep)
+        
+      } // END else if(currentSetting.optimizationMethod.toLowerCase().indexOf("too few experiments") != -1)
+      else {
+        Logger.log("No valid optimization type was selected");
+      }
+    } // END for (var adGroupName in currentSetting.accountMap.campaigns[campaignName].adGroups)
+  } // END for(var campaignName in currentSetting.accountMap.campaigns)
+  
+} // END function writeToSheet()
+        
+function addStyleToSheet(dataSheet) {
+  var numRows = dataSheet.getDataRange().getNumRows();
+  var numColumns = dataSheet.getDataRange().getNumColumns();
+    //clicks, clickShare, impressions, impressionShare, ctr, averagePosition, cost, averageCpc, conversionValue, roas, conversions, conversionShare, conversionRate, costPerConversion, convertedClicks, convertedClicksShare, clickConversionRate, costPerConvertedClick, calculation1
+    dataSheet.getRange(2, 6, numRows, 1).setNumberFormat("#,##0"); // len
+    dataSheet.getRange(2, 8, numRows, 1).setNumberFormat("#,##0"); // len
+    dataSheet.getRange(2, 10, numRows, 1).setNumberFormat("#,##0"); // len
+    dataSheet.getRange(2, 12, numRows, 1).setNumberFormat("#,##0"); // len
+    dataSheet.getRange(2, 17, numRows, 1).setNumberFormat("#,##0"); //clicks
+    dataSheet.getRange(2, 18, numRows, 1).setNumberFormat("0.00%"); //clickShare
+    dataSheet.getRange(2, 19, numRows, 1).setNumberFormat("#,##0"); // imp
+    dataSheet.getRange(2, 20, numRows, 1).setNumberFormat("0.00%"); //Imp Share
+    dataSheet.getRange(2, 21, numRows, 1).setNumberFormat("0.00%"); // ctr
+    dataSheet.getRange(2, 22, numRows, 1).setNumberFormat("#,##0.00"); //avgPos
+    dataSheet.getRange(2, 23, numRows, 1).setNumberFormat("#,##0.00"); // cost
+    dataSheet.getRange(2, 24, numRows, 1).setNumberFormat("#,##0.00"); // avgCpc
+    dataSheet.getRange(2, 25, numRows, 1).setNumberFormat("#,##0.00"); // conv val
+    dataSheet.getRange(2, 26, numRows, 1).setNumberFormat("#,##0.00"); // roas
+    dataSheet.getRange(2, 27, numRows, 1).setNumberFormat("#,##0.00"); // conversions
+    dataSheet.getRange(2, 28, numRows, 1).setNumberFormat("0.00%"); // conv share
+    dataSheet.getRange(2, 29, numRows, 1).setNumberFormat("0.00%"); // conversion rate
+    dataSheet.getRange(2, 30, numRows, 1).setNumberFormat("#,##0.00"); // cost / conv
+    dataSheet.getRange(2, 31, numRows, 1).setNumberFormat("#,##0.00"); // converted clicks
+    dataSheet.getRange(2, 32, numRows, 1).setNumberFormat("0.00%"); // conv click share
+    dataSheet.getRange(2, 33, numRows, 1).setNumberFormat("0.00%"); // converted click rate
+    dataSheet.getRange(2, 34, numRows, 1).setNumberFormat("#,##0.00"); // cost / conv. click
+    dataSheet.getRange(2, 35, numRows, 1).setNumberFormat("#,##0.0000"); // calculation 1
+  
+  // sort on type column
+  //dataSheet.getRange(2, 1, numRows, numColumns).sort(4,5);
+}
+  
+  
+
+  function addCharacterCountColumns() {
+  var numRows = currentSetting.analysisSheet.getDataRange().getNumRows() - 1;
+  currentSetting.analysisSheet.getRange(2, 8, numRows, 1).setFormulaR1C1("=LEN(R[0]C[-1])");
+  currentSetting.analysisSheet.getRange(2, 10, numRows, 1).setFormulaR1C1("=LEN(R[0]C[-1])");
+  currentSetting.analysisSheet.getRange(2, 12, numRows, 1).setFormulaR1C1("=LEN(R[0]C[-1])");
+  currentSetting.analysisSheet.getRange(2, 14, numRows, 1).setFormulaR1C1("=LEN(R[0]C[-1])");        
+}
+  
+  
+  function sortAds() {
+  
+  for(var campaignName in currentSetting.accountMap.campaigns) {
+    for (var adGroupName in currentSetting.accountMap.campaigns[campaignName].adGroups) {
+      currentSetting.sortedAds = new Array();
+      for(var key in currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads) {
+        var value = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[key][currentSetting.sortBy];
+        currentSetting.sortedAds.push({'key': key, 'value': value});
+        //Logger.log(key + "    " + value);
+      }
+      currentSetting.sortedAds.sort(function(a,b) {
+        return b.value - a.value; // DESC sort
+      });
+      
+      for(var i = 0; i < currentSetting.sortedAds.length; i++) {
+        var thisKey = currentSetting.sortedAds[i].key;
+        //Logger.log(thisKey);
+        currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].sortedAdList.push(thisKey);
+      }
+    }
+  }
+} // END function sortAds()
+
+
+  function getLabelsForAd(adGroupId,adId) {
+    
+    var labelName = "";
+    
+    var uniqueAdId = [];
+    var uniqueId = new Array(adGroupId, adId);
+    uniqueAdId.push(uniqueId);
+    
+    var adSelector = AdWordsApp
+     .ads()
+     .withIds(uniqueAdId);
+    
+    var adIterator = adSelector.get();
+    while (adIterator.hasNext()) {
+      Logger.log("Labels: Ad Found");
+      var ad = adIterator.next();
+      var labelIterator = ad.labels()
+        .orderBy("Name")
+        .get();
+      
+      while (labelIterator.hasNext()) {
+        var label = labelIterator.next();
+        labelName += label.getName();
+      }                
+    }
+
+    return(labelName);    
+  } // END function getLabelsForAd(adId,adGroupId)
+  
+  
+  function getLabelsForAdGroup(adGroupId) {
+    
+    var labelName = "";
+    
+    var uniqueAdGroupId = [];
+    uniqueAdGroupId.push(adGroupId);
+    
+    var adGroupSelector = AdWordsApp
+     .adGroups()
+     .withIds(uniqueAdGroupId);
+    
+    var adGroupIterator = adGroupSelector.get();
+    while (adGroupIterator.hasNext()) {
+      Logger.log("Labels: Ad Group Found");
+      var adGroup = adGroupIterator.next();
+      
+      var labelIterator = adGroup.labels()
+      .orderBy("Name")
+      .get();
+      
+      while (labelIterator.hasNext()) {
+        var label = labelIterator.next();
+        labelName += label.getName();
+        break;
+      }                
+    }
+    return(labelName);    
+  } // END function getExperimentLabel(adId,adGroupId)
+
+  function addCalculatedMetrics() {
+    for(var campaignName in currentSetting.accountMap.campaigns) {
+      for (var adGroupName in currentSetting.accountMap.campaigns[campaignName].adGroups) {
+        var adGroupId = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].adGroupId;
+        
+        var adGroupClicks = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].Clicks;
+        var adGroupImpressions = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].Impressions;
+        var adGroupConversions = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].Conversions;
+        var adGroupConvertedClicks = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ConvertedClicks;
+        
+        //Logger.log("adGroupClicks: " + adGroupClicks);
+        //Logger.log("adGroupImpressions: " + adGroupImpressions);
+        
+        for(var adId in currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads) {
+          var thisAd = currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId];
+          var adClicks = thisAd.Clicks;
+          //Logger.log("adClicks: " + adClicks);
+          var adImpressions = thisAd.Impressions;
+          var adConversions = thisAd.Conversions;
+          var adConvertedClicks = thisAd.ConvertedClicks;
+          
+          if(adGroupClicks) {
+            var clickShare = parseFloat(adClicks / adGroupClicks);
+          } else {
+            var clickShare = 0;
+          }
+          if(adGroupImpressions) {
+            var impressionShare = parseFloat(adImpressions / adGroupImpressions);
+          } else {
+            var impressionShare = 0;
+          }
+          if(adGroupConversions) {
+            var conversionShare = parseFloat(adConversions / adGroupConversions);
+          } else {
+            var conversionShare = 0; 
+          }
+          if(adConvertedClicks) {
+            var convertedClicksShare = parseFloat(adConvertedClicks / adConvertedClicks);
+          } else {
+            var convertedClicksShare = 0; 
+          }
+          
+          currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId].ClickShare = clickShare;
+          currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId].ImpressionShare = impressionShare;
+          currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId].ConversionShare = conversionShare;
+          currentSetting.accountMap.campaigns[campaignName].adGroups[adGroupName].ads[adId].ConvertedClicksShare = convertedClicksShare;
+          
+          if(DEBUG==1) Logger.log("clickShare: " + clickShare);
+          if(DEBUG==1) Logger.log("impressionShare: " + impressionShare);
+          if(DEBUG==1) Logger.log("conversionShare: " + conversionShare);
+          if(DEBUG==1) Logger.log("convertedClicksShare: " + convertedClicksShare);
+        }
+      }
+    }
+  }
+
+function getFloat (input) {
+    if(!input || input == "" || typeof(input) === 'undefined') var input = "0.0";
+    input = input.toString();
+    var output = parseFloat(input.replace(/,/g, ""));
+    return output;
+  }
+
+function sendEmailNotifications(emailAddresses, subject, body ) {
+	
+  var finalSubject = subject + " - " + AdWordsApp.currentAccount().getName() + " (" + AdWordsApp.currentAccount().getCustomerId() + ")"
+    
+    
+  if(AdWordsApp.getExecutionInfo().isPreview()) {
+    var finalBody = "<b>This script ran in preview mode. No changes were made to your account.</b><br/>" + body;
+  } else {
+    var finalBody = body;
+  }
+    
+  MailApp.sendEmail({
+    to:emailAddresses, 
+    subject:  finalSubject,
+    htmlBody: finalBody
+  });
+  
+  if(DEBUG == 1) Logger.log("email sent to " + emailAddresses + ": " + finalSubject);
+  
+}
+
+function getCampaignsByLabel(label)
+  {
+    var matchedCampaigns = new Object();
+    matchedCampaigns.ids = new Array();
+    
+    var campaignIterator = AdWordsApp.campaigns()
+    .withCondition("LabelNames CONTAINS_ANY ['" + label + "']")
+    .get();
+    while(campaignIterator.hasNext()) {
+      var campaign = campaignIterator.next();
+      var campaignId = campaign.getId();
+      var campaignName = campaign.getName();
+      matchedCampaigns.ids.push(campaignId);
+      matchedCampaigns.names.push(campaignName);
+    } 
+    matchedCampaigns.selectorStringForReports = "CampaignId IN [" + matchedCampaigns.ids + "]";
+    matchedCampaigns.selectorStringForScripts = "CampaignName IN [" + matchedCampaigns.names.join('","') + "]";
+    Logger.log("matchedCampaigns.selectorStringForScripts: " + matchedCampaigns.selectorStringForScripts);
+    return(matchedCampaigns);
+  }
+
+function getCampaignsByName(campaignName, caseSensitive, exactMatch) {
+    var campaignNameSelector = new Object();
+    if(exactMatch) {
+      var operator = "=";
+    } else {
+      if (caseSensitive) {
+        var operator = "CONTAINS";
+      } else {
+        var operator = "CONTAINS_IGNORE_CASE";
+      }
+    }
+    
+    if(campaignName.indexOf("'") != -1) {
+      var needle = '"' + campaignName + '"';
+    } else {
+      var needle = "'" + campaignName + "'";
+    }
+    
+    campaignNameSelector.forReports = "CampaignName " + operator + " " + needle;
+    campaignNameSelector.forScripts = "CampaignName " + operator + " " + needle;
+    return(campaignNameSelector);
+  }
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.