Vários proponentes: conta única

This script is for a single account. For operating on multiple accounts in a Manager Account, use the Manager Account version of the script.

A otimização dos lances de palavra-chave é uma das atividades mais importantes do gerenciamento de contas do Google AdWords. Os lances de palavra-chave têm um impacto direto sobre o canal de um anúncio (a melhor classificação na Pesquisa Google), bem como seu custo. Os anunciantes costumam desenvolver suas próprias estratégias de lances personalizadas para conseguir atender às respectivas metas.

As regras automatizadas são um recurso eficiente do Google AdWords que permite que os anunciantes modifiquem lances de palavras-chave, atendendo a determinados critérios, e isso é feito dentro de um agendamento. Normalmente, os anunciantes acabam criando um número grande de regras automatizadas, o que acaba dificultando o gerenciamento delas.

O recurso Vários proponentes oferece funcionalidade semelhante à das regras automatizadas com base em uma planilha. Cada linha de uma planilha equivale a uma regra automatizada inteira. O gerenciamento de cem regras (uma tarefa difícil no Google AdWords) torna-se muito mais fácil.

A planilha acima demonstra uma única regra que

  • Procura THIS_WEEK_SUN_TODAY nas estatísticas.
  • Encontra todas as palavras-chave na Campanha 1 que receberam mais de 1 impressão e cuja CTR (taxa de cliques) é maior que 25%.
  • Aumenta seus lances em 10%, sem exceder US$ 1,40.

Como funciona

É necessário manter as seguintes colunas da planilha: Ação, Argumento e Limite de parada. Você pode adicionar ou remover outras colunas conforme a necessidade. Além disso, um grande número de colunas pode ser usado. Veja a seguir exemplos válidos de nomes de coluna e valores de células correspondentes:

  • Coluna: CampaignName STARTS_WITH '?', valor de célula: Indonesia_
  • Coluna: Conversions >= ?, valor de célula: 4
  • Coluna: Status IN [?], valor de célula: 'ENABLED', 'PAUSED'

O símbolo ? no nome da coluna é substituído pelo valor na linha correspondente. Consulte a documentação referente a KeywordSelector para ver um grupo completo de colunas suportadas.

Ação é um dos seguintes:

  • Multiplicar por - multiplica o lance de palavra-chave pelo Argumento. 1.1 aumentará o lance palavra-chave em 10%. 0.8 o diminuirá em 20%.
  • Adicionar - adiciona o Argumento ao lance de palavra-chave. 0.3 diminuirá o lance em US$ 0,30 (considerando que a conta esteja em USD). 0.8 o diminuirá em US$ 0,14.
  • Definir como CPC de primeira página - define o lance de palavra-chave como o CPC (custo por clique) de primeira página. O Argumento é ignorado.
  • Definir como CPC da parte superior da página: define o lance de palavra-chave como o CPC da parte superior da página. O Argumento é ignorado.

Limite de parada é usado para limitar as alterações no lance que o script faz. Se as alterações aplicadas ao lance forem positivas, ele não ficará maior do que o limite de parada. Se a alteração for negativa, o lance não ficará menor do que o limite de parada. Por exemplo, se, no momento, o lance de palavra-chave for de US$ 2,00, e você estiver aplicando um aumento de 25% com um limite de parada de US$ 3,00, o lance será de US$ 2,50. Porém, se o limite de parada for definido em US$ 2,30, o lance também será de US$ 2,30.

A coluna Resultados é gerada automaticamente pelo script. Ela conterá todos os erros que uma execução pode encontrar ou uma indicação do número de palavras-chave que o script buscou e tentou alterar. "Tentativa de alteração" não significa "alteração real": se você tentar atribuir um lance negativo a uma palavra-chave, ela não funcionará. Lembre-se de verificar os registros de execução para ver exatamente o que o script fez. A coluna Resultados é a última coluna da planilha que será lida. Se você adicionar alguma condição depois da coluna Resultados, ela não será aplicada.

Agendamento

As opções de agendamento mais usadas para regras de lances são Diariamente ou Semanalmente. Saiba como a frequência do agendamento interagirá com o período de estatísticas selecionado por você. Como as estatísticas do Google AdWords podem atrasar até três horas, evite agendar seu script Por hora.

Em alguns casos, pode ser que agendar o script não faça diferença nenhuma. Só faça o que gera algum resultado.

Configuração

  • Configure um script com base em planilha usando o código-fonte abaixo. Use a planilha modelo Vários licitantes.
  • Não se esqueça de atualizar SPREADSHEET_URL no código.
  • Visualize o script antes de executá-lo.
  • Considere se é necessário programar o script.

Código-fonte

// 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 Multi Bidder
 *
 * @overview The Multi Bidder script offers functionality similar to that of
 *     Automated Rules based on a spreadsheet. See
 *     https://developers.google.com/adwords/scripts/docs/solutions/multi-bidder
 *     for more details.
 *
 * @author AdWords Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 1.0.3
 *
 * @changelog
 * - version 1.0.3
 *   - Replaced deprecated keyword.getMaxCpc() and keyword.setMaxCpc().
 * - version 1.0.2
 *   - Added validation of user settings.
 * - version 1.0.1
 *   - Improvements to time zone handling.
 * - version 1.0
 *   - Released initial version.
 */

var SPREADSHEET_URL = 'YOUR_SPREADSHEET_URL';

var spreadsheetAccess = new SpreadsheetAccess(SPREADSHEET_URL, 'Rules');

var totalColumns;

function main() {
  // Make sure the spreadsheet is using the account's timezone.
  spreadsheetAccess.spreadsheet.setSpreadsheetTimeZone(
      AdWordsApp.currentAccount().getTimeZone());
  spreadsheetAccess.spreadsheet.getRangeByName('account_id').setValue(
      AdWordsApp.currentAccount().getCustomerId());

  var columns = spreadsheetAccess.sheet.getRange(5, 2, 5, 100).getValues()[0];
  for (var i = 0; i < columns.length; i++) {
    if (columns[i].length == 0 || columns[i] == 'Results') {
      totalColumns = i;
      break;
    }
  }
  if (columns[totalColumns] != 'Results') {
    spreadsheetAccess.sheet.getRange(5, totalColumns + 2, 1, 1).
        setValue('Results');
  }
  // clear the results column
  spreadsheetAccess.sheet.getRange(6, totalColumns + 2, 1000, 1).clear();

  var row = spreadsheetAccess.nextRow();

  while (row != null) {
    var argument;
    var stopLimit;
    try {
      argument = parseArgument(row);
      stopLimit = parseStopLimit(row);
    } catch (ex) {
      logError(ex);
      row = spreadsheetAccess.nextRow();
      continue;
    }
    var selector = AdWordsApp.keywords();
    for (var i = 3; i < totalColumns; i++) {
      var header = columns[i];
      var value = row[i];
      if (!isNaN(parseFloat(value)) || value.length > 0) {
        if (header.indexOf("'") > 0) {
          value = value.replace(/\'/g, "\\'");
        } else if (header.indexOf('\"') > 0) {
          value = value.replace(/"/g, '\\\"');
        }
        var condition = header.replace('?', value);
        selector.withCondition(condition);
      }
    }
    selector.forDateRange(spreadsheetAccess.spreadsheet.
        getRangeByName('date_range').getValue());

    var keywords = selector.get();

    try {
      keywords.hasNext();
    } catch (ex) {
      logError(ex);
      row = spreadsheetAccess.nextRow();
      continue;
    }

    var fetched = 0;
    var changed = 0;

    while (keywords.hasNext()) {
      var keyword = keywords.next();
      var oldBid = keyword.bidding().getCpc();
      var action = row[0];
      var newBid;

      fetched++;
      if (action == 'Add') {
        newBid = addToBid(oldBid, argument, stopLimit);
      } else if (action == 'Multiply by') {
        newBid = multiplyBid(oldBid, argument, stopLimit);
      } else if (action == 'Set to First Page Cpc' ||
          action == 'Set to Top of Page Cpc') {
        var newBid = action == 'Set to First Page Cpc' ?
            keyword.getFirstPageCpc() : keyword.getTopOfPageCpc();
        var isPositive = newBid > oldBid;
        newBid = applyStopLimit(newBid, stopLimit, isPositive);
      }
      if (newBid < 0) {
        newBid = 0.01;
      }
      newBid = newBid.toFixed(2);
      if (newBid != oldBid) {
        changed++;
      }
      keyword.bidding().setCpc(newBid);
    }
    logResult('Fetched ' + fetched + '\nChanged ' + changed);

    row = spreadsheetAccess.nextRow();
  }

  spreadsheetAccess.spreadsheet.getRangeByName('last_execution')
      .setValue(new Date());
}

function addToBid(oldBid, argument, stopLimit) {
  return applyStopLimit(oldBid + argument, stopLimit, argument > 0);
}

function multiplyBid(oldBid, argument, stopLimit) {
  return applyStopLimit(oldBid * argument, stopLimit, argument > 1);
}

function applyStopLimit(newBid, stopLimit, isPositive) {
  if (stopLimit) {
    if (isPositive && newBid > stopLimit) {
      newBid = stopLimit;
    } else if (!isPositive && newBid < stopLimit) {
      newBid = stopLimit;
    }
  }
  return newBid;
}

function parseArgument(row) {
  if (row[1].length == 0 && (row[0] == 'Add' || row[0] == 'Multiply by')) {
    throw ('\"Argument\" must be specified.');
  }
  var argument = parseFloat(row[1]);
  if (isNaN(argument)) {
    throw 'Bad Argument: must be a number.';
  }
  return argument;
}
function parseStopLimit(row) {
  if (row[2].length == 0) {
    return null;
  }
  var limit = parseFloat(row[2]);
  if (isNaN(limit)) {
    throw 'Bad Argument: must be a number.';
  }
  return limit;
}
function logError(error) {
  spreadsheetAccess.sheet.getRange(spreadsheetAccess.currentRow(),
      totalColumns + 2, 1, 1)
  .setValue(error)
  .setFontColor('#c00')
  .setFontSize(8)
  .setFontWeight('bold');
}
function logResult(result) {
  spreadsheetAccess.sheet.getRange(spreadsheetAccess.currentRow(),
      totalColumns + 2, 1, 1)
  .setValue(result)
  .setFontColor('#444')
  .setFontSize(8)
  .setFontWeight('normal');
}

function SpreadsheetAccess(spreadsheetUrl, sheetName) {
  Logger.log('Using spreadsheet - %s.', spreadsheetUrl);
  this.spreadsheet = validateAndGetSpreadsheet(spreadsheetUrl);

  this.sheet = this.spreadsheet.getSheetByName(sheetName);
  this.cells = this.sheet.getRange(6, 2, this.sheet.getMaxRows(),
      this.sheet.getMaxColumns()).getValues();
  this.rowIndex = 0;

  this.nextRow = function() {
    for (; this.rowIndex < this.cells.length; this.rowIndex++) {
      if (this.cells[this.rowIndex][0]) {
        return this.cells[this.rowIndex++];
      }
    }
    return null;
  };
  this.currentRow = function() {
    return this.rowIndex + 5;
  };
}

/**
 * Validates the provided spreadsheet URL
 * to make sure that it's 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 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.');
  }
  return SpreadsheetApp.openByUrl(spreadsheeturl);
}

Looking for the Manager Account (MCC) version? Click here

Enviar comentários sobre…

Precisa de ajuda? Acesse nossa página de suporte.