Rotulador de palavra-chave: 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.

Às vezes, fazer alterações em grande escala nas palavras-chave, como desativar aquelas que apresentam desempenho insatisfatório, é uma tarefa monótona. O script do Rotulador de palavras-chave simplifica essa tarefa por meio da aplicação automática de rótulos para as palavras-chave com base nas regras que você definir. Quando os rótulos são aplicados, você pode filtrar as palavras-chave na IU do Google AdWords e aplicar as alterações desejadas com facilidade, ou fazer alterações nas palavras-chave usando outro script.

Veja a seguir alguns exemplos de como esse script pode ser usado:

  • Rotular as palavras-chave que tiveram um desempenho insatisfatório recentemente. Em seguida, você pode filtrar essas palavras-chave na IU do Google AdWords e modificar os lances delas, ou pausar/removê-las.
  • Rotular as palavras-chave associadas à sua marca, ou seja, aquelas que contêm um nome próprio associado à sua marca, como o nome de um dos seus produtos. Posteriormente, é possível usar esse rótulo para segmentar o Relatório de desempenho por palavra-chave e entender melhor seu desempenho.
  • Rotular palavras-chave cujos lances você deseja alterar. Em seguida, você poderá analisar os rótulos na IU do Google AdWords antes de realmente fazer as alterações usando Edições em massa.
  • Rotular todas as palavras-chave com o Índice de qualidade delas. Posteriormente, você pode rotular as palavras-chave cujo Índice de qualidade atual não corresponde ao anterior (conforme indicado no rótulo original) para que você possa analisá-las.
  • Usar combinações dos itens acima, além de outras abordagens.

Quando novas palavras-chave são rotuladas, o script envia um e-mail com um link para uma planilha.

Como funciona

O script permite que você defina regras usando um formato simples com estes campos:

  • conditions: uma lista opcional de condições KeywordSelector. Essas condições podem, por exemplo, selecionar palavras-chave com base nas suas estatísticas de desempenho.
  • dateRange: um período KeywordSelector opcional para usar na seleção com base nos campos de estatísticas. Se ele for omitido, um período padrão será usado no script.
  • filter: uma função opcional para aplicar às palavra-chave depois que elas forem recuperadas para definir com mais clareza se as palavras-chave correspondem à regra. O filtro é usado em certos campos de palavras-chave para expressar uma lógica mais complexa que não pode ser expressa em conditions.
  • labelName: um nome de rótulo obrigatório para aplicar às palavras-chave que correspondem à regra e ainda não têm esse rótulo.

Veja um exemplo da regra para identificar e rotular palavras-chave com desempenho insatisfatório associados à sua marca:

{
  conditions: [
    'Ctr < 0.02',
    'AverageCpc > 1',
  ],
  dateRange: 'LAST_7_DAYS',
  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'
}

Esta regra aplica um rótulo a todas as palavras-chave com CTR abaixo de 2% e CPC médio acima de US$ 1 nos últimos sete dias, se o texto da palavra-chave contiver pelo menos uma dos três nomes da marca do produto.

Normalmente, só convém atribuir rótulos às palavras-chave que estão ativas e pertencem a um grupo de anúncios e uma campanha ativos. Em vez de especificar essas condições em cada regra, o script permite que você forneça as condições globais que são usadas por todas as regras:

GLOBAL_CONDITIONS: [
  'CampaignStatus = ENABLED',
  'AdGroupStatus = ENABLED',
  'Status = ENABLED'
]

A base do script é uma função que aceita uma regra, cria um KeywordSelector usando as condições globais e específicas da regra e aplica o filtro às palavras-chave resultantes:

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;
}

O script envia um e-mail com um link para uma planilha que lista todas as palavras-chave rotuladas. Em seguida, é possível fazer login na IU do Google AdWords para ver se você deseja fazer alguma modificação a essas palavras-chave, como pausar ou removê-las ou até alterar os lances delas.

Programação

A frequência com que você programará a execução do script (e até mesmo considerar a possibilidade de fazer isso ou não) depende dos seus objetivos com o processo de rotulagem. Se, por exemplo, você pretende rotular as palavras-chave com desempenho insatisfatório, convém programar o script para ser executado semanal ou mesmo diariamente, para que você possa identificar e corrigir rapidamente as palavras-chave com desempenho insatisfatório. Por outro lado, se você deseja usar o script para facilitar o trabalho pontual de rotular palavras-chave, não há necessidade de programar o script para ser executado regularmente.

Configuração

  • Crie um novo script do Google AdWords usando o código-fonte abaixo. Use uma cópia desta planilha modelo.
  • Atualize a matriz RULES para expressar as regras dos rótulos. O código-fonte abaixo mostra um exemplo de como rotular as palavras-chave de desempenho insatisfatório, tanto aquelas que estão associadas à sua marca como as mais genéricas.
  • Não se esqueça de atualizar SPREADSHEET_URL e RECIPIENT_EMAILS no seu 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 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 [adwords-scripts@googlegroups.com]
 *
 * @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.');
  }
}

Enviar comentários sobre…

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