Automação Google Ads: Termos adicionados e Rótulos

Nessa série especial, reunimos alguns scripts úteis para você automatizar e aumentar o retorno de suas campanhas no Google Ads. Confira abaixo como automatizar o Google Ads para “Trabalhar com termos adicionados e Rótulos”.

 

1. Rótulo de contagem regressiva para termos adicionados – Por Russel Savage. Este é um excelente script para manter o controle de termos que foram recentemente adicionados, e portanto, não apresentam um histórico de estatísticas consolidados, assim, você evitar de pausá-los ou fazer alterações antes do tempo.

Sempre que você adicionar novos elementos à sua conta, poderá aplicar um rótulo a ele usando o formato LABEL_PREFIX_. Portanto, se você quiser que seus scripts ignorem um novo elemento por 30 dias, aplique o rótulo “days_left_30” nesse elemento. Se você programar o script para ser executado todos os dias, o número de dias restantes no marcador será reduzido em um por dia. Quando o número de dias chegar a zero, o rótulo será removido da entidade.

Nos scripts que você deseja ignorar novos elementos, inclua a seguinte função na parte inferior do script (antes da última chave):

function _build_label_list() {
//Build a list of labels to exclude in your .withCondition()
var LABEL_PREFIX = ‘days_left_’;
var label_iter = AdWordsApp.labels().withCondition(“Name STARTS_WITH ‘”+LABEL_PREFIX+”‘”).get();
var label_array = [];
while(label_iter.hasNext()) { label_array.push(label_iter.next().getName()); }
return “‘”+label_array.join(“‘,'”)+”‘”
}

 

E, em seguida, adicione o seguinte
.withCondition (“LabelNames CONTAINS_NONE [” + _build_label_list () + “]”)
para qualquer iterador que você tenha em seus outros scripts. Boa sorte, e se você tiver alguma dúvida, não hesite em perguntar.

//———————————–
// Label Countdown
// Created By: Russ Savage
// FreeAdWordsScripts.com
//———————————–
function main() {
var LABEL_PREFIX = “days_left_”; // you can change this if you want

// First lets build a list of labels to work with
var label_iter = AdWordsApp.labels().withCondition(“Name STARTS_WITH ‘”+LABEL_PREFIX+”‘”).get();
var labels_array = [];
while(label_iter.hasNext()) {
labels_array.push(label_iter.next().getName());
}
if(labels_array.length > 0) {
var labels_str = “[‘” + labels_array.join(“‘,'”) + “‘]”;
// grab all the keywords with the labels we want to countdown
var kw_iter = AdWordsApp.keywords().withCondition(“LabelNames CONTAINS_ANY “+labels_str).get();

while(kw_iter.hasNext()) {
var kw = kw_iter.next();
var l_iter = kw.labels().withCondition(“Name STARTS_WITH ‘”+LABEL_PREFIX+”‘”).get();
var label = l_iter.next(); // lazy here because we know this keyword has a label
var days_left = parseInt(label.getName().substr(LABEL_PREFIX.length)) – 1;
kw.removeLabel(label.getName());
if(days_left != 0) {
var new_label_name = LABEL_PREFIX+days_left;
// Create a new label if it doesn’t exist
if(labels_array.indexOf(new_label_name) == -1) {
AdWordsApp.createLabel(new_label_name);
labels_array.push(new_label_name);
}
kw.applyLabel(new_label_name);
}
}
}
}

 

2. Junte Rótulos de Múltiplas Campanhas – Russel Savage. O script auxilia outro script de agrupar campanhas do autor, ele mantém todas os rótulos das palavras-chave das campanhas agrupadas.]

//———————————–
// Merge Labels from Multiple Campaigns
// Created By: Russ Savage
// FreeAdWordsScripts.com
//———————————–
var DESTINATION_CAMPAIGN_NAME = “Destination Campaign Name”;
var ORIGIN_CAMPAIGN_NAMES = [“Origin Campaign Name 1″,”Origin Campaign Name 2”];

function main() {
var label_iter = AdWordsApp.labels().get();
while(label_iter.hasNext()) {
var label = label_iter.next();
//Pre-build all the iterators
var iters = [
label.campaigns().withCondition(“Name IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.adGroups().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.ads().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.keywords().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get()
];
for(var i in iters) {
var iter = iters[i];
while(iter.hasNext()) {
_copyLabels(iter.next());
}
}
}
}

//Copies the labels from entity in Origin campaign
//to entity with the same name in dest campaign
function _copyLabels(entity) {
var iter;
if(_getEntityType(entity) == “Campaign”) {
// it’s a campaign
iter = AdWordsApp.campaigns()
.withCondition(“Name = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.get();
} else if(_getEntityType(entity) == “AdGroup”) {
// it’s an adgroup
iter = AdWordsApp.adGroups()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“Name = ‘”+entity.getName()+”‘”)
.get();
} else if(_getEntityType(entity) == “Ad”) {
// it’s an ad
iter = AdWordsApp.ads()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“AdGroupName = ‘”+entity.getAdGroup().getName()+”‘”)
.withCondition(“Headline = ‘”+entity.getHeadline()+”‘”)
.withCondition(“Description1 = ‘”+entity.getDescription1()+”‘”)
.withCondition(“Description2 = ‘”+entity.getDescription2()+”‘”)
.withCondition(“DisplayUrl = ‘”+entity.getDisplayUrl()+”‘”)
.get();
} else if(_getEntityType(entity) == “Keyword”) {
// it’s a keyword
iter = AdWordsApp.keywords()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“AdGroupName = ‘”+entity.getAdGroup().getName()+”‘”)
.withCondition(“Text = ‘”+entity.getText()+”‘”)
.withCondition(“KeywordMatchType = ‘”+entity.getMatchType()+”‘”)
.get();
}

while(iter.hasNext()) {
_copyLabelsHelper(entity,iter.next());
}

}

//Copy the labels form orig entity to dest entity
function _copyLabelsHelper(orig,dest) {
var label_iter = orig.labels().get();
while(label_iter.hasNext()) {
dest.applyLabel(label_iter.next().getName());
}
}

//Returns a text representation of an entity
//For a better way, check: http://goo.gl/kZL3X
function _getEntityType(obj) {
if(typeof(obj[‘getCampaign’]) == “undefined”) {
return ‘Campaign’;
}
if(typeof(obj[‘getAdGroup’]) == “undefined”) {
return ‘AdGroup’;
}
if(typeof(obj[‘getHeadline’]) != “undefined”) {
return “Ad”;
}
if(typeof(obj[‘getText’]) != “undefined”) {
return “Keyword”;
}
return null;
}//———————————–
// Merge Labels from Multiple Campaigns
// Created By: Russ Savage
// FreeAdWordsScripts.com
//———————————–
var DESTINATION_CAMPAIGN_NAME = “Destination Campaign Name”;
var ORIGIN_CAMPAIGN_NAMES = [“Origin Campaign Name 1″,”Origin Campaign Name 2”];

function main() {
var label_iter = AdWordsApp.labels().get();
while(label_iter.hasNext()) {
var label = label_iter.next();
//Pre-build all the iterators
var iters = [
label.campaigns().withCondition(“Name IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.adGroups().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.ads().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get(),
label.keywords().withCondition(“CampaignName IN [‘”+ORIGIN_CAMPAIGN_NAMES.join(“‘,'”)+”‘]”).get()
];
for(var i in iters) {
var iter = iters[i];
while(iter.hasNext()) {
_copyLabels(iter.next());
}
}
}
}

//Copies the labels from entity in Origin campaign
//to entity with the same name in dest campaign
function _copyLabels(entity) {
var iter;
if(_getEntityType(entity) == “Campaign”) {
// it’s a campaign
iter = AdWordsApp.campaigns()
.withCondition(“Name = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.get();
} else if(_getEntityType(entity) == “AdGroup”) {
// it’s an adgroup
iter = AdWordsApp.adGroups()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“Name = ‘”+entity.getName()+”‘”)
.get();
} else if(_getEntityType(entity) == “Ad”) {
// it’s an ad
iter = AdWordsApp.ads()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“AdGroupName = ‘”+entity.getAdGroup().getName()+”‘”)
.withCondition(“Headline = ‘”+entity.getHeadline()+”‘”)
.withCondition(“Description1 = ‘”+entity.getDescription1()+”‘”)
.withCondition(“Description2 = ‘”+entity.getDescription2()+”‘”)
.withCondition(“DisplayUrl = ‘”+entity.getDisplayUrl()+”‘”)
.get();
} else if(_getEntityType(entity) == “Keyword”) {
// it’s a keyword
iter = AdWordsApp.keywords()
.withCondition(“CampaignName = ‘”+DESTINATION_CAMPAIGN_NAME+”‘”)
.withCondition(“AdGroupName = ‘”+entity.getAdGroup().getName()+”‘”)
.withCondition(“Text = ‘”+entity.getText()+”‘”)
.withCondition(“KeywordMatchType = ‘”+entity.getMatchType()+”‘”)
.get();
}

while(iter.hasNext()) {
_copyLabelsHelper(entity,iter.next());
}

}

//Copy the labels form orig entity to dest entity
function _copyLabelsHelper(orig,dest) {
var label_iter = orig.labels().get();
while(label_iter.hasNext()) {
dest.applyLabel(label_iter.next().getName());
}
}

//Returns a text representation of an entity
//For a better way, check: http://goo.gl/kZL3X
function _getEntityType(obj) {
if(typeof(obj[‘getCampaign’]) == “undefined”) {
return ‘Campaign’;
}
if(typeof(obj[‘getAdGroup’]) == “undefined”) {
return ‘AdGroup’;
}
if(typeof(obj[‘getHeadline’]) != “undefined”) {
return “Ad”;
}
if(typeof(obj[‘getText’]) != “undefined”) {
return “Keyword”;
}
return null;
}

 

3. Rótulos com as datas de criação – Por Russel Savage. Rotule com a data de criação seus anúncios, grupo de anúncios, campanhas e palavras-chave com esse script. Assim, é possível ter um controle histórico de suas alterações.

Essas informações simplesmente não são rastreadas no Google AdWords. A melhor coisa é descobrir quando seu anúncio começou a receber impressões e presumir que foi quando foi criado (se um anúncio for criado, mas ninguém o vir, ele realmente existe?).

Por isso, para ajudar-me a acompanhar a criação dos meus anúncios , juntei o seguinte script para aplicar rótulos em meus anúncios com a data da primeira impressão. Dessa forma, posso descobrir quais anúncios eu criei e garantir que não tomo providências em relação a algo que seja muito novo. Eu também posso fazer alterações em todos os anúncios construídos em um determinado dia com relativa facilidade na interface do usuário do Google Ads, basta selecionar o rótulo correto.

 

/**************************************
* Track Entity Creation Date
* Version 1.4
* Changelog v1.4
* – Removed apiVersion from reporting call
* Changelog v1.3
* – Updated script to handle all entities
* Changelog v1.2
* – Fixed an issue with comparing dates
* ChangeLog v1.1
* – Updated logic to work with larger accounts
* Created By: Russ Savage
* http://www.FreeAdWordsScripts.com
**************************************/
//All my labels will start with this. For example: Created:2013-05-01
var LABEL_PREFIX = ‘Created:’;
var DAYS_IN_REPORT = 30;
var ENTITY = ‘ad’; //or adgroup or keyword or campaign

function main() {
//First we get the impression history of our entity
var ret_map = getImpressionHistory();
//Then we apply our labels
applyLabels(ret_map);
}

//Function to apply labels to the ads in an account
function applyLabels(ret_map) {
var iter;
if(ENTITY === ‘campaign’) { iter = AdWordsApp.campaigns().get(); }
if(ENTITY === ‘adgroup’) { iter = AdWordsApp.adGroups().get(); }
if(ENTITY === ‘ad’) { iter = AdWordsApp.ads().get(); }
if(ENTITY === ‘keyword’) { iter = AdWordsApp.keywords().get(); }

while(iter.hasNext()) {
var entity = iter.next();
var id = entity.getId();
if(ret_map[id]) {
var label_name = LABEL_PREFIX+Utilities.formatDate(ret_map[id], AdWordsApp.currentAccount().getTimeZone(), “yyyy-MM-dd”);
createLabelIfNeeded(label_name);
entity.applyLabel(label_name);
}
}
}

//This is a helper function to create the label if it does not already exist
function createLabelIfNeeded(name) {
if(!AdWordsApp.labels().withCondition(“Name = ‘”+name+”‘”).get().hasNext()) {
AdWordsApp.createLabel(name);
}
}

//A helper function to find the date days ago
function getDateDaysAgo(days) {
var the_past = new Date();
the_past.setDate(the_past.getDate() – days);
return Utilities.formatDate(the_past,AdWordsApp.currentAccount().getTimeZone(),”yyyyMMdd”);
}

//A helper function to compare dates.
//Copied from: http://goo.gl/uW48a
function diffDays(firstDate,secondDate) {
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
return Math.round(Math.abs((firstDate.getTime() – secondDate.getTime())/(oneDay)));
}

function getImpressionHistory() {
var API_VERSION = { includeZeroImpressions : false };
var first_date = new Date(’10/23/2000’);
var max_days_ago = diffDays(first_date,new Date());
var cols = [‘Date’,’Id’,’Impressions’];
var report = {
‘campaign’ : ‘CAMPAIGN_PERFORMANCE_REPORT’,
‘adgroup’ : ‘ADGROUP_PERFORMANCE_REPORT’,
‘ad’ : ‘AD_PERFORMANCE_REPORT’,
‘keyword’ : ‘KEYWORDS_PERFORMANCE_REPORT’}[ENTITY];
var ret_map = {};
var prev_days_ago = 0;
for(var i = DAYS_IN_REPORT; i < max_days_ago; i+=DAYS_IN_REPORT) {
var start_date = getDateDaysAgo(i);
var end_date = getDateDaysAgo(prev_days_ago);
var date_range = start_date+’,’+end_date;
Logger.log(‘Getting data for ‘ + date_range);
var query = [‘select’,cols.join(‘,’),’from’,report,’during’,date_range].join(‘ ‘);
var report_iter = AdWordsApp.report(query, API_VERSION).rows();
if(!report_iter.hasNext()) { Logger.log(‘No more impressions found. Breaking.’); break; } // no more entries
while(report_iter.hasNext()) {
var row = report_iter.next();
if(ret_map[row[‘Id’]]) {
var [year,month,day] = (row[‘Date’]).split(‘-‘);
var from_row = new Date(year, parseFloat(month)-1, day);
var from_map = ret_map[row[‘Id’]];

if(from_row < from_map) {
ret_map[row[‘Id’]] = from_row;
}
} else {
var [year,month,day] = (row[‘Date’]).split(‘-‘);
ret_map[row[‘Id’]] = new Date(year, parseFloat(month)-1, day);
}
}
prev_days_ago = i;
}
return ret_map;
}

4. Dashboard da conta por Rótulos – Por Frederick Vallaeys. Agregue os resultados em uma planilha do Google que possuem um rótulo no Google Ads. Crie um dashboard apenas com as palavras-chave que possuem o rótulo de “melhor performance”, por exemplo.

var SPREADSHEET = “new”; // Put the URL of the Google Sheet here – make sure your AdWords username has edit access to this sheet
var LABELS = new Array(“Labels1”, “Labels2”);
var LEVEL = “campaigns”; // Allowed values: campaigns, keywords, ad groups
var METRICS = new Array({name:”Conversions”, type:”long”, ratio:0, modifierForNewMetric:1, modifierForOldMetric:1}, {name:”ConversionValue”, type:”long”, ratio:0}, {name:”Clicks”, type:”int”, ratio:0}, {name:”Cost”, type:”long”, ratio:0}, {name:”Impressions”, type:”long”, ratio:0});
var CALCULATEDMETRICS = new Array({name:”ROAS”, type:”ratio”, formula:”ConversionValue/Cost”}, {name:”100% ROAS”, type:”static”, formula:”1″}, {name:”Ctr”, type:”ratio”, formula:”Clicks/Impressions”}, {name:”Conversion Rate”, type:”ratio”, formula:”Conversions/Clicks”}, {name:”Conversions Per Imp”, type:”ratio”, formula:”Conversions/Impressions”});
var CHARTMETRICS = new Array({name:”Conversions”, includeComparison:1}, {name:”ROAS”, includeComparison:1, secondMetric:”100% ROAS”}, {name:”Clicks”, includeComparison:1}, {name:”Impressions”, includeComparison:1}, {name:”Ctr”, includeComparison:1}, {name:”Conversion Rate”, includeComparison:1}, {name:”Conversions Per Imp”, includeComparison:1});
var AGGREGATESTATSBYLABEL = 1;
var STARTDAYSAGO = 365;
var TIMESEGMENT = “Week”; // Allowed Values: Week, Date, Month, Quarter
var THOUSANDSSEPARATOR = “,”;
var INCLUDETOTALS = 1;
var CHARTWIDTH = 400;
var CHARTHEIGHT = 200;

var COMPARETODAYSAGO = STARTDAYSAGO;

function main() {

// Set up Dates
// ————
var oldStartDate = getDateInThePast(STARTDAYSAGO + COMPARETODAYSAGO);
var oldEndDate = getDateInThePast(COMPARETODAYSAGO + 1);
var newStartDate = getDateInThePast(STARTDAYSAGO);
var newEndDate = getDateInThePast(1);
//Logger.log(“oldStartDate: ” + oldStartDate);
//Logger.log(“oldEndDate: ” + oldEndDate);
//Logger.log(“newStartDate: ” + newStartDate);
//Logger.log(“newEndDate: ” + newEndDate);

curr = new Date();
var diffLastMonday = – curr.getDay() + 1;
var quarterMonth = (Math.floor(curr.getMonth()/3)*3)+1;

if(TIMESEGMENT == “Week”) {
var reportDates = new Array();
var periodsAgo = Math.floor(1 – (STARTDAYSAGO + COMPARETODAYSAGO) / 7);
//Logger.log(“weeksAgo: ” + periodsAgo);
for(var i = periodsAgo; i <= 0; i++) {
var periodStartDate = new Date(curr.getTime() + (diffLastMonday * 3600 * 24 * 1000) + (3600 * 24 * 1000 * 7 * i));
//Logger.log(“mondayDate ” + i + “: ” + mondayDate.yyyymmdd());
reportDates.push(periodStartDate.yyyymmdd());
}
} else if(TIMESEGMENT == “Date”) {
var reportDates = new Array();
var periodsAgo = 1 – (STARTDAYSAGO + COMPARETODAYSAGO);
for(var i = periodsAgo; i < 0; i++) {
var periodStartDate = new Date(curr.getTime() + (3600 * 24 * 1000 * i));
//Logger.log(“periodStartDate ” + i + “: ” + periodStartDate.yyyymmdd());
reportDates.push(periodStartDate.yyyymmdd());
}
} else if(TIMESEGMENT == “Month”) {
var reportDates = new Array();
var periodsAgo = Math.floor(1 – (STARTDAYSAGO + COMPARETODAYSAGO) / 30.41);
for(var i = periodsAgo; i <= 0; i++) {
var periodStartDate = new Date(curr.getTime() + (3600 * 24 * 1000 * 30.41 * i));
//Logger.log(“periodStartDate ” + i + “: ” + periodStartDate.yyyymmdd());
var yyyy = periodStartDate.getFullYear().toString();
var mm = (periodStartDate.getMonth()+1).toString(); // getMonth() is zero-based
var startDate = yyyy + “-” + (mm[1]?mm:”0″+mm[0]) + “-” + “01”; // padding
reportDates.push(startDate);
}
} else if(TIMESEGMENT == “Quarter”) {
var reportDates = new Array();
var periodsAgo = Math.floor(1 – (STARTDAYSAGO + COMPARETODAYSAGO) / 91.25);
for(var i = periodsAgo; i <= 0; i++) {
var periodStartDate = new Date(curr.getTime() + (3600 * 24 * 1000 * 91.25 * i));
//Logger.log(“periodStartDate ” + i + “: ” + periodStartDate.yyyymmdd());
var yyyy = periodStartDate.getFullYear().toString();
var mm = (Math.floor(periodStartDate.getMonth()/3)*3)+1; // getMonth() is zero-based
mm = mm.toString();
var startDate = yyyy + “-” + (mm[1]?mm:”0″+mm[0]) + “-” + “01”; // padding
reportDates.push(startDate);
}
}

for(var l = 0; l < reportDates.length; l++){
var dateOut = reportDates[l];
//Logger.log(dateOut);
}

// SET UP SPREADSHEET
// ——————-
if(SPREADSHEET.toLowerCase().indexOf(“new”) != -1)
{
var spreadsheet = SpreadsheetApp.create(“Dashboard: ” + LEVEL + ” ” + TIMESEGMENT);
var spreadsheetUrl = spreadsheet.getUrl();
} else {
var spreadsheetUrl = SPREADSHEET;
}
var spreadsheet = SpreadsheetApp.openByUrl(spreadsheetUrl);
//spreadsheet.addEditor(“[email protected]”);
//Logger.log(“acct mgr: ” + accountManagers);
//var accountManagersArray = accountManagers.trim().split(“,”);
//spreadsheet.addEditors(accountManagersArray);

var chartSheet = spreadsheet.getSheetByName(“Charts”);
if(chartSheet) {
spreadsheet.deleteSheet(chartSheet)
chartSheet = spreadsheet.insertSheet(“Charts”);
//chartSheet.clear();
} else {
var chartSheet = spreadsheet.insertSheet(“Charts”);
}
chartSheet.insertColumnsAfter(7, 7*CHARTMETRICS.length);

var totalsSheet = spreadsheet.getSheetByName(“Totals”);
if(totalsSheet) {
spreadsheet.deleteSheet(totalsSheet);
var totalsSheet = spreadsheet.insertSheet(“Totals”);
//totalsSheet.clear();
} else {
var totalsSheet = spreadsheet.insertSheet(“Totals”);
}
totalsSheet.insertColumnsAfter(7, 7*CHARTMETRICS.length);

Logger.log(“Your Dashboard is located at ” + spreadsheetUrl);

var aggregateTotals = new Array();

// Process each label
for(var labelCounter = 0; labelCounter < LABELS.length; labelCounter++) {
var label = LABELS[labelCounter];
Logger.log(“Label: ” + label);

var metricArray = new Array();
var metricArrayForQuery = new Array();

var headerRow = new Array(“New Date”, “Compared To Date”);

for(var metricCounter = 0; metricCounter<METRICS.length; metricCounter++) {
metricArray.push(METRICS[metricCounter].name);
metricArrayForQuery.push(METRICS[metricCounter].name);
var newModifier = METRICS[metricCounter].modifierForNewMetric || 1;
var oldModifier = METRICS[metricCounter].modifierForOldMetric || 1;
var newMetricText = “Current ” + METRICS[metricCounter].name + ” (x” + newModifier + “)”;
var oldMetricText = “Previous ” + METRICS[metricCounter].name + ” (x” + oldModifier + “)”;
headerRow.push(newMetricText, oldMetricText);
}

for(var metricCounter = 0; metricCounter<CALCULATEDMETRICS.length; metricCounter++) {
var name = CALCULATEDMETRICS[metricCounter].name;
metricArray.push(name);
var formula = CALCULATEDMETRICS[metricCounter].formula;
var newMetricText = “Current ” + name + ” (” + formula + “)”;
var oldMetricText = “Previous ” + name + ” (” + formula + “)”;
headerRow.push(newMetricText, oldMetricText);
}

if(labelCounter == 0) {
totalsSheet.appendRow(headerRow);
}

var results = getIds(label, LEVEL);
var ids = results.ids;
var idNames = results.names;
if(AGGREGATESTATSBYLABEL == 1) {
var chartTitle = label;
var newTotals = getStatsForIds(ids, metricArrayForQuery, newStartDate, newEndDate, label, “new”);
var oldTotals = getStatsForIds(ids, metricArrayForQuery, oldStartDate, oldEndDate, label, “old”);

var sheet = spreadsheet.getSheetByName(label);
if(sheet) {
sheet.clear();
} else {
var sheet = spreadsheet.insertSheet(label);
}
sheet.appendRow(headerRow);

// Loop through all the date ranges
var halfWay = parseInt(reportDates.length / 2);
for(var j = 0; j < halfWay; j++) {
var oldKey = reportDates[j];
var newKeyIndex = j+halfWay;
var newKey = reportDates[newKeyIndex];
//Logger.log(j + “. ” + oldKey + newKeyIndex + “. ” + newKey);
//var newMetrics = newTotals[newKey];
//var oldMetrics = oldTotals[oldKey];
var thisLine = new Array(newKey, oldKey);
for(var k = 0; k < METRICS.length; k++) {
var metric = METRICS[k].name;
if(!newTotals[newKey]) {
var newStat = 0;
} else {
var newStat = newTotals[newKey][metric];
}
if(!oldTotals[oldKey]) {
var oldStat = 0;
} else {
var oldStat = oldTotals[oldKey][metric];
}
thisLine.push(newStat, oldStat);

// Keep total stats by time segment
if(!aggregateTotals[newKey]) {
aggregateTotals[newKey] = new Object();
aggregateTotals[newKey][metric] = new Object();
aggregateTotals[newKey][metric] = newStat;
} else {
if(!aggregateTotals[newKey][metric]) {
aggregateTotals[newKey][metric] = new Object();
aggregateTotals[newKey][metric] = newStat;
} else {
aggregateTotals[newKey][metric] += newStat;
}
}

if(!aggregateTotals[oldKey]) {
aggregateTotals[oldKey] = new Object();
aggregateTotals[oldKey][metric] = new Object();
aggregateTotals[oldKey][metric] = oldStat;
} else {
if(!aggregateTotals[oldKey][metric]) {
aggregateTotals[oldKey][metric] = new Object();
aggregateTotals[oldKey][metric] = oldStat;
} else {
aggregateTotals[oldKey][metric] += oldStat;
}
}
//Logger.log(newKey + ” : ” + metric + ” : ” + newStat);
//Logger.log(oldKey + ” : ” + metric + ” : ” + oldStat);
}

// Calculated Metrics
for(var metricCounter = 0; metricCounter < CALCULATEDMETRICS.length; metricCounter++) {
var name = CALCULATEDMETRICS[metricCounter].name;
var formula = CALCULATEDMETRICS[metricCounter].formula;
var type = CALCULATEDMETRICS[metricCounter].type;

if(type.toLowerCase().indexOf(“ratio”) != -1) {
var formulaParts = formula.split(“/”);
if(newTotals[newKey]) {
var newTop = newTotals[newKey][formulaParts[0]];
var newBottom = newTotals[newKey][formulaParts[1]];
var newStat = newTop / newBottom;
} else {
var newStat = 0;
}

if(oldTotals[oldKey]) {
var oldTop = oldTotals[oldKey][formulaParts[0]];
var oldBottom = oldTotals[oldKey][formulaParts[1]];
var oldStat = oldTop / oldBottom;
} else {
var oldStat = 0;
}
//Logger.log(“name: ” + name + ” – formula: ” + formula + “newTop: ” + newTop + ” newBottom: ” + newBottom);
} else if (type.toLowerCase().indexOf(“static”) != -1) {
var newStat = formula;
var oldStat = formula;
}
thisLine.push(newStat, oldStat);
}

sheet.appendRow(thisLine);

}

// Create the charts
insertChart(sheet, chartSheet, labelCounter, chartTitle, metricArray);
var numChartsCreated = labelCounter;

// FOR NOT AGGREGATED STATS
} else {
// Go one ID at a time
for(var idCounter = 0; idCounter < ids.length; idCounter++) {
var id = “” + ids[idCounter];
var name = idNames[idCounter];
var chartTitle = name;
//Logger.log(“id: ” + id);
var thisIdArray = new Array(id);
var newTotals = getStatsForIds(thisIdArray, metricArrayForQuery, newStartDate, newEndDate, label, “new”);
var oldTotals = getStatsForIds(thisIdArray, metricArrayForQuery, oldStartDate, oldEndDate, label, “old”);

var sheet = spreadsheet.getSheetByName(name);
if(sheet) {
sheet.clear();
} else {
var sheet = spreadsheet.insertSheet(name);
}
sheet.appendRow(headerRow);

// Loop through all the date ranges
var halfWay = parseInt(reportDates.length / 2);
for(var j = 0; j < halfWay; j++) {
var oldKey = reportDates[j];
var newKeyIndex = j+halfWay;
var newKey = reportDates[newKeyIndex];
//Logger.log(j + “. ” + oldKey + newKeyIndex + “. ” + newKey);
//var newMetrics = newTotals[newKey];
//var oldMetrics = oldTotals[oldKey];
var thisLine = new Array(newKey, oldKey);
for(var k = 0; k < METRICS.length; k++) {
var metric = METRICS[k].name;
if(!newTotals[newKey]) {
var newStat = 0;
} else {
var newStat = newTotals[newKey][metric];
}
if(!oldTotals[oldKey]) {
var oldStat = 0;
} else {
var oldStat = oldTotals[oldKey][metric];
}
thisLine.push(newStat, oldStat);

// Keep total stats by time segment
if(!aggregateTotals[newKey]) {
aggregateTotals[newKey] = new Object();
aggregateTotals[newKey][metric] = new Object();
aggregateTotals[newKey][metric] = newStat;
} else {
if(!aggregateTotals[newKey][metric]) {
aggregateTotals[newKey][metric] = new Object();
aggregateTotals[newKey][metric] = newStat;
} else {
aggregateTotals[newKey][metric] += newStat;
}
}

if(!aggregateTotals[oldKey]) {
aggregateTotals[oldKey] = new Object();
aggregateTotals[oldKey][metric] = new Object();
aggregateTotals[oldKey][metric] = oldStat;
} else {
if(!aggregateTotals[oldKey][metric]) {
aggregateTotals[oldKey][metric] = new Object();
aggregateTotals[oldKey][metric] = oldStat;
} else {
aggregateTotals[oldKey][metric] += oldStat;
}
}
//Logger.log(newKey + ” : ” + metric + ” : ” + newStat);
//Logger.log(oldKey + ” : ” + metric + ” : ” + oldStat);
}

// Calculated Metrics
for(var metricCounter = 0; metricCounter < CALCULATEDMETRICS.length; metricCounter++) {
var name = CALCULATEDMETRICS[metricCounter].name;
var formula = CALCULATEDMETRICS[metricCounter].formula;
var type = CALCULATEDMETRICS[metricCounter].type;

if(type.toLowerCase().indexOf(“ratio”) != -1) {
var formulaParts = formula.split(“/”);
if(newTotals[newKey]) {
var newTop = newTotals[newKey][formulaParts[0]];
var newBottom = newTotals[newKey][formulaParts[1]];
var newStat = newTop / newBottom;
} else {
var newStat = 0;
}

if(oldTotals[oldKey]) {
var oldTop = oldTotals[oldKey][formulaParts[0]];
var oldBottom = oldTotals[oldKey][formulaParts[1]];
var oldStat = oldTop / oldBottom;
} else {
var oldStat = 0;
}
//Logger.log(“name: ” + name + ” – formula: ” + formula + “newTop: ” + newTop + ” newBottom: ” + newBottom);
} else if (type.toLowerCase().indexOf(“static”) != -1) {
var newStat = formula;
var oldStat = formula;
}
thisLine.push(newStat, oldStat);
}

sheet.appendRow(thisLine);

}

// Create the charts

insertChart(sheet, chartSheet, idCounter, chartTitle, metricArray);
}
var numChartsCreated = idCounter;
}

} // END for(var labelCounter = 0; labelCounter < LABELS.length; labelCounter++)

if(INCLUDETOTALS == 1) {
// Output totals to another sheet
processTotals(aggregateTotals, totalsSheet, halfWay, reportDates);
// Create the chart
chartTitle = “Totals”;
var offsetCounter = numChartsCreated+1;
insertChart(totalsSheet, chartSheet, offsetCounter, chartTitle, metricArray);
}
}

// FUNCTION processTotals
function processTotals(aggregateTotals, totalsSheet, halfWay, reportDates) {

for(var j = 0; j < halfWay; j++) {
var oldKey = reportDates[j];
var newKeyIndex = j+halfWay;
var newKey = reportDates[newKeyIndex];
//Logger.log(j + “. ” + oldKey + newKeyIndex + “. ” + newKey);
var newMetrics = aggregateTotals[newKey];
var oldMetrics = aggregateTotals[oldKey];
var thisLine = new Array(newKey, oldKey);
for(var k = 0; k < METRICS.length; k++) {
var metric = METRICS[k].name;
if(!aggregateTotals[newKey]) {
var newStat = 0;
} else {
var newStat = aggregateTotals[newKey][metric];
}
if(!aggregateTotals[oldKey]) {
var oldStat = 0;
} else {
var oldStat = aggregateTotals[oldKey][metric];
}
thisLine.push(newStat, oldStat);

//Logger.log(newKey + ” : ” + metric + ” : ” + newStat);
//Logger.log(oldKey + ” : ” + metric + ” : ” + oldStat);
}

// Calculated Metrics
for(var metricCounter = 0; metricCounter < CALCULATEDMETRICS.length; metricCounter++) {
var name = CALCULATEDMETRICS[metricCounter].name;
var formula = CALCULATEDMETRICS[metricCounter].formula;
var type = CALCULATEDMETRICS[metricCounter].type;

if(type.toLowerCase().indexOf(“ratio”) != -1) {
var formulaParts = formula.split(“/”);
var newTop = aggregateTotals[newKey][formulaParts[0]];
var newBottom = aggregateTotals[newKey][formulaParts[1]];
var newStat = newTop / newBottom;
var oldTop = aggregateTotals[oldKey][formulaParts[0]];
var oldBottom = aggregateTotals[oldKey][formulaParts[1]];
var oldStat = oldTop / oldBottom;
//Logger.log(“name: ” + name + ” – formula: ” + formula + “newTop: ” + newTop + ” newBottom: ” + newBottom);
} else if (type.toLowerCase().indexOf(“static”) != -1) {
var newStat = formula;
var oldStat = formula;
}
thisLine.push(newStat, oldStat);
}

totalsSheet.appendRow(thisLine);

}
}

// FUNCTION insertChart
function insertChart(sheet, chartSheet, offsetCounter, chartTitle, metricArray) {
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
//var numCols = rows.getNumColumns();

for(var chartCounter = 0; chartCounter < CHARTMETRICS.length; chartCounter++) {
var metric = CHARTMETRICS[chartCounter].name;
var secondMetric = CHARTMETRICS[chartCounter].secondMetric;
var width = CHARTWIDTH;
var height = CHARTHEIGHT;

//Logger.log(“chart for ” + chartTitle + ” ” + metric);
var metricIndex = metricArray.indexOf(metric);
var metricColumn1 = metricIndex*2+3;
var metricColumn2 = metricIndex*2+4;

var secondMetricIndex = metricArray.indexOf(secondMetric);
var secondMetricColumn1 = secondMetricIndex*2+3;
var secondMetricColumn2 = secondMetricIndex*2+4;

var chartStartRow = 1+offsetCounter*22;
var chartStartCol = 1+chartCounter*7;

var xOffset = width*chartCounter;
var yOffset = offsetCounter*height;
var numCols = 1+CHARTMETRICS[chartCounter].includeComparison;
if(!secondMetric) {
var chart = chartSheet.newChart()
.setPosition(1, 1, xOffset, yOffset)
.setOption(“width”, width)
.setOption(“height”, height)
.asLineChart()
.setTitle(chartTitle)
.setYAxisTitle(metric)
.addRange(sheet.getRange(1,1,numRows,1))
.addRange(sheet.getRange(1, metricColumn1, numRows, numCols))
.build();
} else {
var chart = chartSheet.newChart()
.setPosition(1, 1, xOffset, yOffset)
.setOption(“width”, width)
.setOption(“height”, height)
.asLineChart()
.setTitle(chartTitle)
.setYAxisTitle(metric)
.addRange(sheet.getRange(1,1,numRows,1))
.addRange(sheet.getRange(1, metricColumn1, numRows, numCols))
.addRange(sheet.getRange(1, secondMetricColumn1, numRows, numCols))
.build();
}
chartSheet.insertChart(chart);
var chartSheetRows = chartSheet.getDataRange();
var chartSheetNumRows = chartSheetRows.getNumRows();
var chartSheetNumColumns = chartSheetRows.getNumColumns();
}
chartSheet.insertRowsAfter(chartSheetNumRows, 22);
}

// FUNCTION getIds — Fetches the IDs of the items with the specified label
function getIds(label, LEVEL) {

var ids = new Array();
var results = new Object();
results.ids = new Array();
results.names = new Array();

if(LEVEL.toLowerCase().indexOf(“campaigns”) != -1) {
var campaignIterator = AdWordsApp.campaigns()
.withCondition(“LabelNames CONTAINS_ANY [‘” + label + “‘]”)
.get();

while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
var campaignName = campaign.getName();
var id = campaign.getId();
results.ids.push(id);
results.names.push(campaignName);
//Logger.log(campaignName + ” id: ” + id);
}
} else if(LEVEL.toLowerCase().indexOf(“ad groups”) != -1) {
var adGroupIterator = AdWordsApp.adGroups()
.withCondition(“LabelNames CONTAINS_ANY [‘” + label + “‘]”)
.get();

while (adGroupIterator.hasNext()) {
var adGroup = adGroupIterator.next();
var adGroupName = adGroup.getName();
var id = adGroup.getId();
results.ids.push(id);
results.names.push(adGroupName);
//Logger.log(adGroupName + ” id: ” + id);
}
} else if(LEVEL.toLowerCase().indexOf(“keywords”) != -1) {
var keywordIterator = AdWordsApp.keywords()
.withCondition(“LabelNames CONTAINS_ANY [‘” + label + “‘]”)
.get();

while (keywordIterator.hasNext()) {
var keyword = keywordIterator.next();
var keywordText = keyword.getText();
var id = keyword.getId();
results.ids.push(id);
results.names.push(keywordText);
//Logger.log(keywordText + ” id: ” + id);
}
}

return results;

}

// FUNCTION getStatsForIds — gets the stats for the items
function getStatsForIds(ids, metricArrayForQuery, startDate, endDate, label, oldOrNew) {

var totals = new Array();
var keys = new Array();

var idString = ids.join();

if(LEVEL.toLowerCase().indexOf(“campaigns”) != -1) {
var reportType = “CAMPAIGN_PERFORMANCE_REPORT”;
var idType = “CampaignId”;
} else if(LEVEL.toLowerCase().indexOf(“ad groups”) != -1) {
var reportType = “ADGROUP_PERFORMANCE_REPORT”;
var idType = “AdGroupId”;
} else if(LEVEL.toLowerCase().indexOf(“keywords”) != -1) {
var reportType = “KEYWORDS_PERFORMANCE_REPORT”;
var idType = “Id”;
}

var report1 = AdWordsApp.report(
‘SELECT ‘ + metricArrayForQuery.join() + ‘,’ + TIMESEGMENT + ‘ ‘ +
‘FROM ‘ + reportType + ‘ ‘ +
‘WHERE ‘ + idType + ‘ IN [‘ + idString + ‘] ‘ +
‘DURING ‘ + startDate + “,” + endDate );
var rows1 = report1.rows();

while (rows1.hasNext()) {
var row = rows1.next();
var stats = new Array();
for(var i = 0; i < METRICS.length; i++) {
var metric = METRICS[i].name;
if(oldOrNew.toLowerCase().indexOf(“new”) != -1) {
var modifierForMetric = METRICS[i].modifierForNewMetric || 1;
} else if(oldOrNew.toLowerCase().indexOf(“old”) != -1) {
var modifierForMetric = METRICS[i].modifierForOldMetric || 1;
}
//Logger.log(“modifierForMetric: ” + modifierForMetric);
//Logger.log(“Metric: ” + metric);
stats[metric] = {};
stats[metric].value = row[metric];
stats[metric].modifierForMetric = modifierForMetric;
//Logger.log(label + ” – ” + metric + “: ” + stats[metric].value);
}
//var conversions = parseInt(row[‘Conversions’]);
if(TIMESEGMENT.toLowerCase().indexOf(“week”) != -1) {
var timeKey = row[‘Week’];
} else if(TIMESEGMENT.toLowerCase().indexOf(“date”) != -1) {
var timeKey = row[‘Date’];
} else if(TIMESEGMENT.toLowerCase().indexOf(“month”) != -1) {
var timeKey = row[‘Month’];
} else if(TIMESEGMENT.toLowerCase().indexOf(“quarter”) != -1) {
var timeKey = row[‘Quarter’];
}
//Logger.log(“timekey: ” + timeKey);
if(!totals[timeKey]) {
totals[timeKey] = new Object();
for(var i = 0; i < METRICS.length; i++) {
var metric = METRICS[i].name;
var type = METRICS[i].type;
if(type.toLowerCase().indexOf(“int”) != -1) {
var value = parseInt(stats[metric].value);
} else if(type.toLowerCase().indexOf(“double”) != -1) {
var value = parseFloat(stats[metric].value);
} else if(type.toLowerCase().indexOf(“long”) != -1) {
var value = parseFloat(stats[metric].value.replace(THOUSANDSSEPARATOR,””));
}
modifierForMetric = stats[metric].modifierForMetric;
totals[timeKey][metric] = value * modifierForMetric;
//Logger.log(“modifierForMetric: ” + modifierForMetric);
//Logger.log(timeKey + “: ” + totals[timeKey][metric]);
}
totals[timeKey].date = timeKey;
} else {
for(var i = 0; i < METRICS.length; i++) {
var metric = METRICS[i].name;
var type = METRICS[i].type;
if(type.toLowerCase().indexOf(“int”) != -1) {
var value = parseInt(stats[metric].value);
} else if(type.toLowerCase().indexOf(“double”) != -1) {
var value = parseFloat(stats[metric].value);
} else if(type.toLowerCase().indexOf(“long”) != -1) {
var value = parseFloat(stats[metric].value.replace(THOUSANDSSEPARATOR,””));
}
modifierForMetric = stats[metric].modifierForMetric;
totals[timeKey][metric] += value * modifierForMetric;
//Logger.log(timeKey + “: ” + totals[timeKey][metric]);
}
}
}

var sortedTotals = sortObj(totals);

return sortedTotals;
//return totals;

}

function sortObj(arr){
// Setup Arrays
var sortedKeys = new Array();
var sortedObj = {};

// Separate keys and sort them
for (var i in arr){
sortedKeys.push(i);
}
sortedKeys.sort();

// Reconstruct sorted obj based on keys
for (var i in sortedKeys){
sortedObj[sortedKeys[i]] = arr[sortedKeys[i]];
}
return sortedObj;
}

// Returns YYYYMMDD-formatted date.
function getDateInThePast(numDays) {
var today = new Date();
today.setDate(today.getDate() – numDays);
return Utilities.formatDate(today, “PST”, “yyyyMMdd”);
}

Date.prototype.yyyymmdd = function() {
var yyyy = this.getFullYear().toString();
var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
var dd = this.getDate().toString();
return yyyy + “-” + (mm[1]?mm:”0″+mm[0]) + “-” + (dd[1]?dd:”0″+dd[0]); // padding
};

 

5. Rótulos de conta – Por Google Ads. Este é um compilado de scripts do Google que possibilita por exemplo, edições em massa de rótulos.

Crie um rótulo de conta

function createAccountLabels() {
var labelName = ‘INSERT_LABEL_NAME_HERE’;

MccApp.createAccountLabel(labelName);
Logger.log(“Label with text = ‘%s’ created.”, labelName);
}

 

Aplicar um marcador de conta a várias contas

function applyAccountLabels() {
var accountIds = [‘INSERT_ACCOUNT_ID_HERE’, ‘INSERT_ACCOUNT_ID_HERE’];
var labelName = ‘INSERT_LABEL_NAME_HERE’;

var accounts = MccApp.accounts().withIds(accountIds).get();
while (accounts.hasNext()) {
var account = accounts.next();
account.applyLabel(labelName);

Logger.log(‘Label with text = “%s” applied to customer id %s.’,
labelName, account.getCustomerId());
}
}

 

Remover um rótulo de conta de várias contas

function removeLabelFromAccounts() {
var accountIds = [‘INSERT_ACCOUNT_ID_HERE’, ‘INSERT_ACCOUNT_ID_HERE’];
var labelName = ‘INSERT_LABEL_NAME_HERE’;

var accounts = MccApp.accounts().withIds(accountIds).get();
while (accounts.hasNext()) {
var account = accounts.next();
account.removeLabel(labelName);

Logger.log(‘Label with text = “%s” removed from customer id %s.’,
labelName, account.getCustomerId());
}
}

 

Selecione uma conta pelo nome do marcador

function selectAccountsByLabelName() {
var labelName = ‘INSERT_LABEL_NAME_HERE’;

var accountIterator = MccApp.accounts()
.withCondition(“LabelNames CONTAINS ‘” + labelName + “‘”)
.get();

while (accountIterator.hasNext()) {
var account = accountIterator.next();
var accountName = account.getName() ? account.getName() : ‘–‘;
Logger.log(‘%s,%s,%s,%s’, account.getCustomerId(), accountName,
account.getTimeZone(), account.getCurrencyCode());
}
}

 

Recuperar todos os marcadores de conta

function getAllAccountLabels() {
var labelIterator = MccApp.accountLabels().get();
while (labelIterator.hasNext()) {
var label = labelIterator.next();

Logger.log(‘Label with id = %s and text = %s was found.’,
label.getId().toFixed(0), label.getName());
}
}

 

Recuperar um rótulo de conta pelo nome dele

function getLabelByName() {
var labelName = ‘INSERT_LABEL_NAME_HERE’;

var labelIterator = MccApp.accountLabels()
.withCondition(“Name CONTAINS ‘” + labelName + “‘”)
.get();

while (labelIterator.hasNext()) {
var label = labelIterator.next();

Logger.log(‘Label with id = %s and text = %s was found.’,
label.getId().toFixed(0), label.getName());
}
}

 

Recuperar rótulos de conta por seus IDs

function getLabelById() {
var labelIterator = MccApp.accountLabels()
.withIds([12345, 67890]) // Replace with label IDs here
.get();

while (labelIterator.hasNext()) {
var label = labelIterator.next();

Logger.log(“Label with id = %s and text = ‘%s’ was found.”,
label.getId().toFixed(0), label.getName());
}
}

6. Rotulador de Palavra-chave – Por Google Ads. Rotule em grande escala as palavras-chave com esse script e depois otimize-as com o filtro de rótulos no Google Ads.

// 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.

/**
* @name Keyword Labeler
*
* @overview The Keyword Labeler script labels keywords based on rules that
* you define. For example, you can create a rule to label keywords that
* are underperforming. Later, you can filter for this label in AdWords
* to decide whether to pause or remove those keywords. Rules don’t have
* to be based solely on a keyword’s performance. They can also be based
* on properties of a keyword such as its text or match type. For example,
* you could define “branded” keywords as those containing proper nouns
* associated with your brand, then label those keywords based on
* different performance thresholds versus “non-branded” keywords.
* Finally, the script sends an email linking to a spreadsheet when new
* keywords have been labeled. See
* https://developers.google.com/adwords/scripts/docs/solutions/labels
* for more details.
*
* @author AdWords Scripts Team [[email protected]]
*
* @version 1.1.2
*
* @changelog
* – version 1.1.2
* – Added validation for external spreadsheet setup.
* – version 1.1.1
* – Improvements to time zone handling.
* – version 1.1
* – Modified to allow generic rules and labeling.
* – version 1.0
* – Released initial version.
*/

var CONFIG = {
// URL of the spreadsheet template.
// This should be a copy of https://goo.gl/uhK6nS.
SPREADSHEET_URL: ‘YOUR_SPREADSHEET_URL’,

// Array of addresses to be alerted via email if labels are applied.
RECIPIENT_EMAILS: [
‘YOUR_EMAIL_HERE’
],

// Selector conditions to apply for all rules.
GLOBAL_CONDITIONS: [
‘CampaignStatus = ENABLED’,
‘AdGroupStatus = ENABLED’,
‘Status = ENABLED’
],

// Default date range over which statistics fields are retrieved.
// Used when fetching keywords if a rule doesn’t specify a date range.
DEFAULT_DATE_RANGE: ‘LAST_7_DAYS’
};

/**
* Defines the rules by which keywords will be labeled.
* The labelName field is required. Other fields may be null.
* @type {Array.<{
* conditions: Array.<string>,
* dateRange: string,
* filter: function(Object): boolean,
* labelName: string,
* }>
* }
*/
var RULES = [
{
conditions: [
‘Ctr < 0.02’,
‘AverageCpc > 1’,
],
filter: function(keyword) {
var brands = [‘Product A’, ‘Product B’, ‘Product C’];
var text = keyword.getText();
for (var i = 0; i < brands.length; i++) {
if (text.indexOf(brand[i]) >= 0) {
return true;
}
}
return false;
},
labelName: ‘Underperforming Branded’
},

{
conditions: [
‘Ctr < 0.01’,
‘AverageCpc > 2’,
],
labelName: ‘Underperforming’
}
];

function main() {
validateEmailAddresses();
var results = processAccount();
processResults(results);
}

/**
* Processes the rules on the current account.
*
* @return {Array.<Object>} An array of changes made, each having
* a customerId, campaign name, ad group name, label name,
* and keyword text that the label was applied to.
*/
function processAccount() {
ensureAccountLabels();
var changes = applyLabels();

return changes;
}

/**
* Processes the results of the script.
*
* @param {Array.<Object>} changes An array of changes made, each having
* a customerId, campaign name, ad group name, label name,
* and keyword text that the label was applied to.
*/
function processResults(changes) {
if (changes.length > 0) {
var spreadsheetUrl = saveToSpreadsheet(changes, CONFIG.RECIPIENT_EMAILS);
sendEmail(spreadsheetUrl, CONFIG.RECIPIENT_EMAILS);
} else {
Logger.log(‘No labels were applied.’);
}
}

/**
* Retrieves the names of all labels in the account.
*
* @return {Array.<string>} An array of label names.
*/
function getAccountLabelNames() {
var labelNames = [];
var iterator = AdWordsApp.labels().get();

while (iterator.hasNext()) {
labelNames.push(iterator.next().getName());
}

return labelNames;
}

/**
* Checks that the account has a label for each rule and
* creates the rule’s label if it does not already exist.
* Throws an exception if a rule does not have a labelName.
*/
function ensureAccountLabels() {
var labelNames = getAccountLabelNames();

for (var i = 0; i < RULES.length; i++) {
var labelName = RULES[i].labelName;

if (!labelName) {
throw ‘Missing labelName for rule #’ + i;
}

if (labelNames.indexOf(labelName) == -1) {
AdWordsApp.createLabel(labelName);
labelNames.push(labelName);
}
}
}

/**
* Retrieves the keywords in an account satisfying a rule
* and that do not already have the rule’s label.
*
* @param {Object} rule An element of the RULES array.
* @return {Array.<Object>} An array of keywords.
*/
function getKeywordsForRule(rule) {
var selector = AdWordsApp.keywords();

// Add global conditions.
for (var i = 0; i < CONFIG.GLOBAL_CONDITIONS.length; i++) {
selector = selector.withCondition(CONFIG.GLOBAL_CONDITIONS[i]);
}

// Add selector conditions for this rule.
if (rule.conditions) {
for (var i = 0; i < rule.conditions.length; i++) {
selector = selector.withCondition(rule.conditions[i]);
}
}

// Exclude keywords that already have the label.
selector.withCondition(‘LabelNames CONTAINS_NONE [“‘ + rule.labelName + ‘”]’);

// Add a date range.
selector = selector.forDateRange(rule.dateRange || CONFIG.DEFAULT_DATE_RANGE);

// Get the keywords.
var iterator = selector.get();
var keywords = [];

// Check filter conditions for this rule.
while (iterator.hasNext()) {
var keyword = iterator.next();

if (!rule.filter || rule.filter(keyword)) {
keywords.push(keyword);
}
}

return keywords;
}

/**
* For each rule, determines the keywords matching the rule and which
* need to have a label newly applied, and applies it.
*
* @return {Array.<Object>} An array of changes made, each having
* a customerId, campaign name, ad group name, label name,
* and keyword text that the label was applied to.
*/
function applyLabels() {
var changes = [];
var customerId = AdWordsApp.currentAccount().getCustomerId();

for (var i = 0; i < RULES.length; i++) {
var rule = RULES[i];
var keywords = getKeywordsForRule(rule);
var labelName = rule.labelName;

for (var j = 0; j < keywords.length; j++) {
var keyword = keywords[j];

keyword.applyLabel(labelName);

changes.push({
customerId: customerId,
campaignName: keyword.getCampaign().getName(),
adGroupName: keyword.getAdGroup().getName(),
labelName: labelName,
keywordText: keyword.getText(),
});
}
}

return changes;
}

/**
* Outputs a list of applied labels to a new spreadsheet and gives editor access
* to a list of provided emails.
*
* @param {Array.<Object>} changes An array of changes made, each having
* a customerId, campaign name, ad group name, label name,
* and keyword text that the label was applied to.
* @param {Array.<Object>} emails An array of email addresses.
* @return {string} The URL of the spreadsheet.
*/
function saveToSpreadsheet(changes, emails) {
var template = validateAndGetSpreadsheet(CONFIG.SPREADSHEET_URL);
var spreadsheet = template.copy(‘Keyword Labels Applied’);

// Make sure the spreadsheet is using the account’s timezone.
spreadsheet.setSpreadsheetTimeZone(AdWordsApp.currentAccount().getTimeZone());

Logger.log(‘Saving changes to spreadsheet at ‘ + spreadsheet.getUrl());

var headers = spreadsheet.getRangeByName(‘Headers’);
var outputRange = headers.offset(1, 0, changes.length);

var outputValues = [];
for (var i = 0; i < changes.length; i++) {
var change = changes[i];
outputValues.push([
change.customerId,
change.campaignName,
change.adGroupName,
change.keywordText,
change.labelName
]);
}
outputRange.setValues(outputValues);

spreadsheet.getRangeByName(‘RunDate’).setValue(new Date());

for (var i = 0; i < emails.length; i++) {
spreadsheet.addEditor(emails[i]);
}

return spreadsheet.getUrl();
}

/**
* Sends an email to a list of email addresses with a link to a spreadsheet.
*
* @param {string} spreadsheetUrl The URL of the spreadsheet.
* @param {Array.<Object>} emails An array of email addresses.
*/
function sendEmail(spreadsheetUrl, emails) {
MailApp.sendEmail(emails.join(‘,’), ‘Keywords Newly Labeled’,
‘Keywords have been newly labeled in your’ +
‘AdWords account(s). See ‘ +
spreadsheetUrl + ‘ for details.’);
}

/**
* DO NOT EDIT ANYTHING BELOW THIS LINE.
* Please modify your spreadsheet URL and email addresses at the top of the file
* only.
*/

/**
* Validates the provided spreadsheet URL and email address
* to make sure that they’re set up properly. Throws a descriptive error message
* if validation fails.
*
* @param {string} spreadsheeturl The URL of the spreadsheet to open.
* @return {Spreadsheet} The spreadsheet object itself, fetched from the URL.
* @throws {Error} If the spreadsheet URL or email hasn’t been set
*/
function validateAndGetSpreadsheet(spreadsheeturl) {
if (spreadsheeturl == ‘YOUR_SPREADSHEET_URL’) {
throw new Error(‘Please specify a valid Spreadsheet URL. You can find’ +
‘ a link to a template in the associated guide for this script.’);
}
var spreadsheet = SpreadsheetApp.openByUrl(spreadsheeturl);
return spreadsheet;
}

/**
* Validates the provided email address to make sure it’s not the default.
* Throws a descriptive error message if validation fails.
*
* @throws {Error} If the list of email addresses is still the default
*/
function validateEmailAddresses() {
if (CONFIG.RECIPIENT_EMAILS &&
CONFIG.RECIPIENT_EMAILS[0] == ‘YOUR_EMAIL_HERE’) {
throw new Error(‘Please specify a valid email address.’);
}
}

 

Como Configurar