Automação Google Ads: Como pausar e deletar anúncios com baixo desempenho.

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 “pausar e deletar anúncios com baixo desempenho”.

 

1. Pausar Anúncios com CTR Baixo – Pelo Russell Savage. Esse script tem como função economizar o tempo de pausar seus anúncios que estão com CTR (Taxa de cliques) baixas e que diminuem seu índice de qualidade de suas palavras-chave.

 

//-----------------------------------
// Pause Ads with Low CTR
// Created By: Russ Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
// Let's start by getting all of the adGroups that are active
var ag_iter = AdWordsApp.adGroups()
.withCondition("Status = ENABLED")
.get();

// Then we will go through each one
while (ag_iter.hasNext()) {
var ag = ag_iter.next();
var ad_iter = ag.ads()
.withCondition("Status = ENABLED")
.forDateRange("ALL_TIME")
.orderBy("Ctr DESC")
.get();
var ad_array = new Array();
while(ad_iter.hasNext()) {
ad_array.push(ad_iter.next());
}
if(ad_array.length > 1) {
for(var i = 1; i < ad_array.length; i++) {
ad_array[i].pause(); //or .remove(); to delete them
}
}
}
}</code

 

2. Pausar Grupo de Anúncios Sem Palavras-chave – Pelo Russel Savage. Agências ou grandes contas de Adwords podem se beneficiar com esse script, uma vez que, ele pausa automaticamente campanhas que não possuem palavras-chave ativadas. Isso pode poupar o seu trabalho em campanhas que tem uma regra de pausar palavras-chaves que não estão trazendo resultado.

/*********************************************
* Pause AdGroups With No Active Keywords
* Version 1.1
* Changelog v1.1
* - Updated for speed and added comments
* Created By: Russ Savage
* FreeAdWordsScripts.com
**********************************************/
function main() {
// Let's start by getting all of the active AdGroups
var agIter = AdWordsApp.adGroups()
.withCondition('CampaignStatus = ENABLED')
.withCondition('Status = ENABLED')
.get();

// It is faster to store them and process them all at once later
var toPause = [];
// Then we will go through each one
while(agIter.hasNext()) {
var ag = agIter.next();
//get all the keywords that are enabled
var kwIter = ag.keywords()
.withCondition("Status = ENABLED")
.get();

//If .hasNext() is true, there is at least 1 kw in the AdGroup
var hasKw = kwIter.hasNext();
if(!hasKw) {
toPause.push(ag);
}
}

// Now we process them all at once to take advantage of batch processing
for(var i in toPause) {
toPause[i].pause();
}
}

 

3. Pausar Todas Palavras-chave Sem Impressões – Pelo Russell Savage. Esse script é uma boa opção para que deseja fazer uma “limpa” em suas palavras-chave que não estão ativando seus anúncios, mantendo somente palavras relevantes.

/*********************************************
* Pause Keywords With No Impressions All Time
* Version 1.1
* Changelog v1.1
* - Updated for speed and added comments
* Created By: Russ Savage
* FreeAdWordsScripts.com
**********************************************/
var TO_NOTIFY = "[email protected]";
function main() {
// Let's start by getting all of the keywords with no impressions
var kwIter = AdWordsApp.keywords()
.withCondition("Impressions = 0") // could be "Clicks = 0" also
.forDateRange("ALL_TIME") // could use a specific date range like "20130101","20131231"
.withCondition("Status = ENABLED")
.withCondition("CampaignStatus = ENABLED")
.withCondition("AdGroupStatus = ENABLED")
.get();

// It is much faster to store all the keywords you want to process
// and then make the changes all at once. This takes advantage
// of the batch processing behind the scenes.
var toPause = [];
while (kwIter.hasNext()) {
var kw = kwIter.next();
toPause.push(kw);
// This is to make sure you see things during the preview
// When you run it for real, you can remove this clause to
// increase speed.
if(AdWordsApp.getExecutionInfo().isPreview() &&
AdWordsApp.getExecutionInfo().getRemainingTime() < 10) {
break;
}
}

// Now go through each one and pause them.
for(var i in toPause) {
toPause[i].pause();
//Or you could use toPause[i].remove(); to delete the keyword altogether
}

// Sent an email to notify you of the changes
MailApp.sendEmail(TO_NOTIFY,
"AdWords Script Paused "+toPause.length+" Keywords.",
"Your AdWords Script paused "+toPause.length+" keywords.");
}

4. Ativar ou Pausar Campanhas, Palavras-chave ou Anúncios em Datas Específicas – Por Russel Savage. Quem trabalha com marketing online deve conhecer a Black Friday e o impacto dela nas vendas nesta data. Com esse script você pode ativar suas campanhas, anúncios e palavras-chave em datas específicas, assim, você pode programar para fazer promoções especiais sem a necessidade de estar presente no momento. Para configurar é necessário rotular suas campanhas, palavras-chave ou anúncios com o rótulo “Pause on”, para pausar, ou “Enable on”, para ativar.

/**************************************************
* Pause or Enable Campaigns, Keywords or Ads on a Given Date
* Version 1.2
* Changelog v1.2 - Added ability to pause Campaigns
* Changelog v1.1 - Added ability to run on Ads
* Created By: Russ Savage
* FreeAdWordsScripts.com
**************************************************/
var ENTITY = 'Keyword'; //or Ad or Campaign
var PAUSE_PREFIX = "Pause on "; //look for labels "Pause on 2013-04-11"
var ENABLE_PREFIX = "Enable on "; //look for labels "Enable on 2013-04-11"

function main() {
var todayStr = Utilities.formatDate(new Date(), AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
var pauseStr = PAUSE_PREFIX+todayStr;
var enableStr = ENABLE_PREFIX+todayStr;
Logger.log("Looking for labels: " + [pauseStr,enableStr].join(' and '));

var labelsArray = buildLabelArray(pauseStr,enableStr);

if(labelsArray.length > 0) {
var labelsStr = "['" + labelsArray.join("','") + "']";
var entityIter;
if(ENTITY === 'Keyword') {
entityIter = AdWordsApp.keywords().withCondition("LabelNames CONTAINS_ANY "+labelsStr).get();
} else if(ENTITY === 'Ad') {
entityIter = AdWordsApp.ads().withCondition("LabelNames CONTAINS_ANY "+labelsStr).get();
} else if(ENTITY === 'Campaign') {
entityIter = AdWordsApp.campaigns().withCondition("LabelNames CONTAINS_ANY "+labelsStr).get();
} else {
throw 'Invaid ENTITY type. Should be Campaign, Keyword or Ad. ENTITY:'+ENTITY;
}

while(entityIter.hasNext()) {
var entity = entityIter.next();
pauseEntity(entity, pauseStr);
enableEntity(entity, enableStr);
}
}
}

//Helper function to build a list of labels in the account
function buildLabelArray(pauseStr,enableStr) {
var labelsArray = [];
try {
var labelIter = AdWordsApp.labels().withCondition("Name IN ['"+pauseStr+"','"+enableStr+"']").get();
while(labelIter.hasNext()) {
labelsArray.push(labelIter.next().getName());
}
return labelsArray;
} catch(e) {
Logger.log(e);
}
return [];
}

//Helper function to pause entities
function pauseEntity(entity, pauseStr) {
var labelIter = entity.labels().withCondition("Name = '"+pauseStr+"'").get();
if(labelIter.hasNext()) {
entity.pause();
entity.removeLabel(pauseStr);
}
}

//Helper function to enable entities
function enableEntity(entity, enableStr) {
var labelIter = entity.labels().withCondition("Name = '"+enableStr+"'").get();
if(labelIter.hasNext()) {
entity.enable();
entity.removeLabel(enableStr);
}
}

 

5. Pausar ao Atingir o Orçamento Mensal – Por Sean Dolan. Esse é um ótimo script para manter seus custos sob controle! Ao atingir um limite do seu orçamento mensal, ele automaticamente vai pausar seus anúncios, impedindo que suas campanhas continuem consumindo.

 

var CUTOFF_COST = 10000;
var CUTOFF_LABEL = "Total Spend cutoff";

function main() {
var label = AdWordsApp.labels().withCondition("Name='" + CUTOFF_LABEL + "'").get().next();

if (AdWordsApp.currentAccount().getStatsFor("THIS_MONTH").getCost() > CUTOFF_COST) {
var campaignIterator = label.campaigns().get();

while (campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
campaign.pause();
}
}
}

 

6. Pausar palavras-chave com índice de qualidade baixo – por Optmyzr. As palavras-chave com índice de qualidade baixo aumentam seu CPC para atingir a posição ideal nas páginas de resultados do Google. Esse script é útil caso você deseje manter uma campanha apenas com palavras-chave acima de um determinado índice de qualidade. Por padrão ele está configurado para pausar índices abaixo de 5.

 

// Copyright www.optmyzr.com all rights reserved. This script is provided on a as-is basis with no guarantee.
// This script may be distributed freely, without changing this notice

function main() {

//EDIT- SECTION

//Enter email address. For mulitple addresses please enter the the addresses separated by a comma.
var email_address = "[email protected]";

//Change the pause value to true to pause the keywords with below quality score.
var pause = false;

//This quality score defines the threshold to find keywords below it.
var quality_score = 5;

//ENTER the number of days you would like to get the stats of keywords for. By default it checks for last 30 days.
var date_range = "LAST_30_DAYS";

//END OF EDIT-SECTION

var workbook = SpreadsheetApp.create("Keywords with low Quality Score (" +
Utilities.formatDate(new Date(), "PST", "MM-dd HH:mm)"));
var currentSheet = workbook.getActiveSheet();
var keyword_found=false;

currentSheet.setName("Overview");
currentSheet.appendRow(["Campaign Name","Adgroup","Keyword","Cost","Impressions","Conversions","Quality Score"]);
currentSheet.getRange("1:1").setFontWeight("bold");

var report = AdWordsApp.report("SELECT CampaignName, AdGroupName, KeywordText, Cost, Impressions, Conversions, QualityScore "+
"FROM KEYWORDS_PERFORMANCE_REPORT "+
"WHERE CampaignStatus= ACTIVE and AdGroupStatus = ENABLED and Status = ACTIVE and QualityScore<"+quality_score+
" DURING "+date_range);

report.exportToSheet(currentSheet);
var rows = report.rows();
if(!rows.hasNext()){
currentSheet.appendRow(["No active Keywords Found"]);
}

MailApp.sendEmail(email_address, "Quality Score Tracker for Keywords", "You can see the keywords on the following url\n\n"+workbook.getUrl());
}

 

7. Apagar anúncios reprovados – por Russell Savage. Ao administrar contas em larga escala, mudanças nas landing pages do site, grupos de anúncios antigos, testes A/B podem fazer seus anúncios serem reprovados. Esse script deixa sua conta mais organizada apagando anúncios que estão reprovados.

 

//-----------------------------------
// Delete Ads That Are Disapproved
// Created By: Russ Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
// Let's start by getting all of the ad that are disapproved
var ad_iter = AdWordsApp.ads()
.withCondition("ApprovalStatus != APPROVED")
.get();

// Then we will go through each one
while (ad_iter.hasNext()) {
var ad = ad_iter.next();
// now we delete the ad
Logger.log("Deleteing ad: " + ad.getHeadline());
ad.remove();
}
}

 

8. Desativar anúncios e palavras-chave para produtos sem estoque – por Russel Savage. Ótimo script para empresas de e-commerce que anunciam no Google Ads, seja no dia-a-dia ou em picos de demandas como no Black Friday, você pode ter seus anúncios e palavras-chave pausados assim que estiverem fora de estoque.

Para que esse script funcione, preciso descobrir o que há de diferente na página quando ela fica sem estoque. Se eu clicar com o botão direito e visualizar a fonte da página, e procurar pelo trabalho “stock”, eu posso ver alguns lugares diferentes onde ele é usado. Um deles é o seguinte que diz “in_stock”: false.

Isso parece promissor. Eu verifico um item em estoque e, com certeza, “in_stock”: true está nessa página.

Tudo bem, agora sei o texto que preciso usar para preencher a variável OUT_OF_STOCK_TEXT no meu código. Agora cada site vai ser um pouco diferente, então eu tenho um script simples que usa a mesma lógica de URL que o script completo que você pode usar para testes.

/ ** **********************************
* Url rápido em estoque / fora do estoque
* Versão 1.0
* Criado por: Russ Savage
* FreeAdWordsScripts.com
********************************** * /
var STRIP_QUERY_STRING = true ;
var WRAPPED_URLS = true ;
var OUT_OF_STOCK_TEXT = ' O texto que identifica um item em falta no estoque vai aqui ' ;
var URL_TO_TEST = ' Seu URL para verificar vai aqui ' ;

função main () {
var urlToTest = URL_TO_TEST ;
urlToTest = cleanUrl (urlToTest);
var htmlCode = UrlFetchApp . buscar (urlToTest). getContentText ();
if ( htmlCode . indexOf ( OUT_OF_STOCK_TEXT ) > = 0 ) {
Logger . log ( ' O item está fora de estoque. ' );
} mais {
Logger . log ( ' O item está em estoque. ' );
}
}

function cleanUrl ( url ) {
if ( WRAPPED_URLS ) {
url = url . substr ( url . lastIndexOf ( ' http ' ));
if ( decodeURIComponent (url) ! == url) {
url = decodeURIComponent (url);
}
}
if ( STRIP_QUERY_STRING ) {
if ( url . indexOf ( ' ? ' ) > = 0 ) {
url = url . split ( ' ? ' ) [ 0 ];
}
}
if ( url . indexOf ( ' { ' ) > = 0 ) {
// Vamos remover os parâmetros da faixa de valor
url = url . substitua ( / \ { [ 0-9a-zA-Z ] + \} / g , ' ' );
}
URL de retorno ;
}

 

Depois de encontrar algum texto HTML na origem da página de destino que identifique se um item está em falta, convém seguir o roteiro completo. Existem algumas outras opções no script que permitem ativar ou desativar várias manipulações de URL no script. E lembre-se de que isso fará uma pausa apenas nos anúncios ou nas palavras-chave vinculados à página com o item esgotado.

 

/ ** **********************************
* Item esgotado
* Versão 1.2
* ChangeLog v1.2
* - ONLY_ACTIVE é usado para filtrar apenas campanhas e grupos de anúncios. Todas as palavras-chave e anúncios nos grupos de anúncios
* ser verificado que resolve o problema "uma vez desativado, sempre desativado".
* - chamada atualizada para obter os URLs finais. Agora chama getFinalUrl e getMobileFinalUrl em vez de getDestinationUrl
* - OUT_OF_STOCK_TEXTS agora pode conter várias coisas para verificar.
* - Se o CAMPAIGN_LABEL não existir, ele será ignorado com um aviso.
* ChangeLog v1.1 - Filtrado campanhas excluídas e grupos de anúncios
* Criado por: Russ Savage
* FreeAdWordsScripts.com
********************************** * /
var URL_LEVEL = ' Anúncio ' ; // ou palavra-chave
var ONLY_ACTIVE = true ; // defina como falso para verificar palavras-chave ou anúncios em todas as campanhas (pausadas e ativas)
var CAMPAIGN_LABEL = ' ' ; // definir isso se você quiser apenas verificar campanhas com esse rótulo
var STRIP_QUERY_STRING = true ; // configure isso para false se as coisas que vierem após o ponto de interrogação forem importantes
var WRAPPED_URLS = true ; // configure isso para true se você usar um terceiro como Marin ou Kenshoo para gerenciar sua conta
// Este é o texto específico (ou textos) para procurar
// na página que indica o item
// está fora de estoque. Se QUALQUER destes corresponderem ao html
// na página, o item é considerado "fora de estoque"
var OUT_OF_STOCK_TEXTS = [
' O texto que identifica um item fora de estoque vai aqui ' ,
' Outra string pode ir aqui, mas não precisa '
];

função main () {
var alreadyCheckedUrls = {};
var iter = buildSelector (). get ();
while ( iter . hasNext ()) {
var entity = iter . next ();
var urls = [];
if ( entity . urls (). getFinalUrl ()) {
urls . push ( entity . urls (). getFinalUrl ());
}
if ( entity . urls (). getMobileFinalUrl ()) {
urls . push ( entity . urls (). getMobileFinalUrl ());
}
para ( var i in urls) {
var url = cleanUrl (urls [i]);
if (alreadyCheckedUrls [url]) {
if (alreadyCheckedUrls [url] === ' esgotado ' ) {
entidade . pausa ();
} mais {
entidade . enable ();
}
} mais {
var htmlCode;
try {
htmlCode = UrlFetchApp . buscar (url). getContentText ();
} pegar (e) {
Logger . log ( ' Houve uma verificação de problemas: ' + url + ' , Ignorando. ' );
continue ;
}
var did_pause = false ;
para ( var x em OUT_OF_STOCK_TEXTS ) {
if ( htmlCode . indexOf ( OUT_OF_STOCK_TEXTS [x]) > = 0 ) {
alreadyCheckedUrls [url] = ' esgotado ' ;
entidade . pausa ();
did_pause = true ;
pausa ;
}
}
if ( ! did_pause) {
alreadyCheckedUrls [url] = ' em estoque ' ;
entidade . enable ();
}
}
Logger . log ( ' Url: ' + url + ' é ' + alreadyCheckedUrls [url]);
}
}
}

function cleanUrl ( url ) {
if ( WRAPPED_URLS ) {
url = url . substr ( url . lastIndexOf ( ' http ' ));
if ( decodeURIComponent (url) ! == url) {
url = decodeURIComponent (url);
}
}
if ( STRIP_QUERY_STRING ) {
if ( url . indexOf ( ' ? ' ) > = 0 ) {
url = url . split ( ' ? ' ) [ 0 ];
}
}
if ( url . indexOf ( ' { ' ) > = 0 ) {
// Vamos remover os parâmetros da faixa de valor
url = url . substitua ( / \ { [ 0-9a-zA-Z ] + \} / g , ' ' );
}
URL de retorno ;
}

function buildSelector () {
var selector = ( URL_LEVEL === ' Ad ' ) ? AdWordsApp . anúncios () : AdWordsApp . palavras-chave ();
seletor = seletor . withCondition ( ' CampaignStatus! = DELETED ' ). withCondition ( ' AdGroupStatus! = DELETED ' );
if ( ONLY_ACTIVE ) {
seletor = seletor . withCondition ( ' CampaignStatus = ENABLED ' );
if ( URL_LEVEL ! == ' Ad ' ) {
seletor = seletor . withCondition ( ' AdGroupStatus = ENABLED ' );
}
}
if ( CAMPAIGN_LABEL ) {
if ( AdWordsApp . labels (). withCondition ( " Nome = ' " + CAMPAIGN_LABEL + " ' " ). get (). hasNext ()) {
var label = AdWordsApp . rótulos (). withCondition ( " Nome = ' " + CAMPAIGN_LABEL + " ' " ). get (). next ();
var campIter = label . campanhas (). get ();
var campaignNames = [];
while ( campIter . hasNext ()) {
campaignNames . push ( campIter . next (). getName ());
}
seletor = seletor . withCondition ( " CampaignName IN [" " + campaignNames . join ( " ',' " ) + " '] " );
} mais {
Logger . log ( ' AVISO: o rótulo da campanha não existe: ' + CAMPAIGN_LABEL );
}
}
seletor de retorno ;
}