Otimização da consulta de pesquisa: conta única

Ícone de relatórios

Esse script compara o desempenho do termo de pesquisa no Relatório de visualização de termos de pesquisa com os limites fornecidos para gerar listas de palavras-chave positivas e negativas (exatas).

Como funciona

Para saber como os relatórios funcionam nos scripts do Google Ads, confira o guia dedicado a relatórios e a página de exemplos de relatórios.

Essa solução gera um relatório de consulta de pesquisa para encontrar termos que podem ser indesejáveis se não tiverem uma taxa de cliques alta o suficiente e os adiciona como palavras-chave negativas para que não acionem seu anúncio.

O script também procura palavras-chave que têm uma alta taxa de cliques, bem como um baixo custo por conversão, e as adiciona como palavras-chave positivas.

Instalação

  • Crie um novo script com o código-fonte abaixo.
  • Durante a visualização, o script provavelmente será concluído dentro da janela de visualização de 30 segundos. Caso contrário, tente alterar a condição DURING LAST_7_DAYS para DURING YESTERDAY.
  • Depois que o script for concluído na visualização, você verá uma lista de palavras-chave que seriam adicionadas como negativas (e, em alguns casos, positivas).

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 Search Query Report
 *
 * @overview The Search Query Report script uses the Search Query Performance
 *     Report to find undesired search terms and add them as negative (or
 *     positive) exact keywords. See
 *     https://developers.google.com/google-ads/scripts/docs/solutions/search-query
 *     for more details.
 *
 * @author Google Ads Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 2.0
 *
 * @changelog
 * - version 2.0
 *   - Updated to use new Google Ads scripts features.
 * - version 1.0.1
 *   - Upgrade to API version v201609.
 * - version 1.0
 *   - Released initial version.
 */

// Minimum number of impressions to consider "enough data"
const IMPRESSIONS_THRESHOLD = 100;
// Cost-per-click (in account currency) we consider an expensive keyword.
const AVERAGE_CPC_THRESHOLD = 1; // $1
// Threshold we use to decide if a keyword is a good performer or bad.
const CTR_THRESHOLD = 0.5; // 0.5%
// If ctr is above threshold AND our conversion cost isn’t too high,
// it’ll become a positive keyword.
const COST_PER_CONVERSION_THRESHOLD = 10; // $10

/**
 * Configuration to be used for running reports.
 */
const REPORTING_OPTIONS = {
  // Comment out the following line to default to the latest reporting version.
  apiVersion: 'v11'
};

function main() {
  const report = AdsApp.report(
      `SELECT search_term_view.search_term, ` +
      `metrics.clicks, ` +
      `metrics.cost_micros, ` +
      `metrics.ctr, ` +
      `metrics.conversions_from_interactions_rate, ` +
      `metrics.cost_per_conversion, ` +
      `metrics.conversions, ` +
      `campaign.id, ` +
      `ad_group.id ` +
      `FROM search_term_view ` +
      `WHERE metrics.conversions > -1 ` +
      `AND metrics.impressions > ${IMPRESSIONS_THRESHOLD} ` +
      `AND metrics.average_cpc > ${AVERAGE_CPC_THRESHOLD} ` +
      `AND segments.date DURING LAST_7_DAYS`, REPORTING_OPTIONS);

  const rows = report.rows();
  const negativeKeywords = {};
  const positiveKeywords = {};
  const allAdGroupIds = {};
  // Iterate through search query and decide whether to
  // add them as positive or negative keywords (or ignore).
  for (const row of rows) {
    if (parseFloat(row['metrics.ctr*100%']) < CTR_THRESHOLD) {
      addToMultiMap(negativeKeywords, row['ad_group.id'],
                    row['search_term_view.search_term']);
      allAdGroupIds[row['ad_group.id']] = true;
    } else if (parseFloat(row['metrics.cost_per_conversion']) <
        COST_PER_CONVERSION_THRESHOLD ||
        !(parseFloat(row['metrics.cost_per_conversion']))) {
        addToMultiMap(positiveKeywords, row['ad_group.id'],
                    row['search_term_view.search_term']);
        allAdGroupIds[row['ad_group.id']] = true;
    }
  }

  // Copy all the adGroupIds from the object into an array.
  const adGroupIdList = [];
  for (const adGroupId in allAdGroupIds) {
    adGroupIdList.push(adGroupId);
  }

  // Add the keywords as negative or positive to the applicable ad groups.
  const adGroups = AdsApp.adGroups().withIds(adGroupIdList).get();
  for (const adGroup of adGroups) {
    if (negativeKeywords[adGroup.getId()]) {
      for (const negativeKeyword of negativeKeywords[adGroup.getId()]) {
        adGroup.createNegativeKeyword(`[${negativeKeyword}]`);
      }
    }
    else if (positiveKeywords[adGroup.getId()]) {
      for (const positiveKeyword of positiveKeywords[adGroup.getId()]) {
        adGroup.newKeywordBuilder()
            .withText(`[${positiveKeyword}]`)
            .build();
      }
    }
  }
}

function addToMultiMap(map, key, value) {
  if (!map[key]) {
    map[key] = [];
  }
  map[key].push(value);
}