Назначение ставок по нескольким параметрам – отдельный аккаунт

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

Одна из важнейших задач при управлении аккаунтами AdWords – оптимизация ставок для ключевых слов, которые напрямую влияют на стоимость и позицию объявлений в результатах поиска. Как правило, в каждом случае разрабатываются собственные стратегии назначения ставок, исходя из требований бизнеса.

С помощью автоматизированных правил AdWords рекламодатели могут корректировать ставки для ключевых слов по заданному графику с учетом определенных условий. Но иногда таких правил становится слишком много, чтобы управлять ими эффективно.

Инструмент назначения ставок по нескольким параметрам позволяет реализовать функции, аналогичные автоматизированным правилам. Для этого используются данные таблицы, каждая строка которой определяет отдельное правило. Таким образом, управлять большим набором правил в AdWords становится проще.

В приведенной выше таблице показано отдельное правило со следующими функциями:

  • Просмотр статистики для переменной диапазона THIS_WEEK_SUN_TODAY.
  • Поиск в кампании Campaign #1 всех ключевых слов, набравших хотя бы два показа, CTR которых выше 25%
  • Увеличение ставок для этих слов на 10% с максимальным ограничением в 1,40 доллара США.

Принцип работы

Не удаляйте столбцы Action (Действие), Argument (Аргумент) и Stop limit (Предел остановки). Другие столбцы можно добавлять и удалять по мере необходимости. Скрипт поддерживает достаточно большое число столбцов. Ниже приводятся примеры допустимых имен столбцов и соответствующих значений ячеек.

  • Столбец: CampaignName STARTS_WITH '?', значение ячейки: Indonesia_.
  • Столбец: Conversions >= ?, значение ячейки: 4.
  • Столбец: Status IN [?], значение ячейки: 'ENABLED', 'PAUSED'.

? – этот символ в названии столбца заменяется значением соответствующей строки. Полную информацию о поддерживаемых столбцах можно найти в документации по KeywordSelector.

Столбец Action (Действие) определяет одну из следующих операций:

  • Multiply by (Умножить) – умножение ставки для ключевого слова на значение в столбце Argument (Аргумент). Например, значение 1.1 определяет увеличение ставки на 10%, а 0.8 – ее снижение на 20%.
  • Add (Добавить) – добавление значения в столбце Argument (Аргумент) к ставке. Например, 0.3 означает увеличение ставки на 0,30 долл. США (если в аккаунте выбрана эта валюта), а 0.8 – ее снижение на 20%.
  • Set to First Page Cpc (Цена за клик на уровне ставки для первой страницы) – назначение ставки, необходимой для показа объявления на первой странице результатов. Значение столбца Argument (Аргумент) игнорируется.
  • Set to Top of Page Cpc (Цена за клик для показа вверху страницы) – назначение ставки, необходимой для показа объявления вверху страницы. Значение столбца Argument (Аргумент) игнорируется.

В столбце Stop Limit (Предел остановки) задается максимальная или минимальная величина ставки для положительных и отрицательных изменений соответственно. Например, если в столбце Stop Limit (Предел остановки) задано значение 3, при увеличении текущей ставки в 2 доллара США на 25% будет получена ставка 2,50 доллара США. Однако если в этом столбце установлен предел в 2,30 доллара США, итоговая ставка будет ограничена именно этой величиной.

Столбец Results (Результаты) заполняется автоматически. Он может содержать сведения об ошибках во время выполнения, а также числе извлеченных ключевых слов и попыток их изменения. Обратите внимание, что не каждая попытка завершается изменением: например, назначение отрицательной ставки выполнено не будет. Фактически выполненные скриптом действия регистрируются в журналах. Условия, добавленные после столбца Results (Результаты), не применяются, поскольку чтение данных после него прекращается.

Планирование

Правила назначения ставок обычно выполняются ежедневно или еженедельно с учетом выбранного периода сбора данных. Поскольку обновление статистики в AdWords может занимать до трех часов, планировать ежечасное выполнение скрипта не рекомендуется.

В некоторых случаях планировать выполнение этого скрипта не требуется вовсе.

Настройка

Исходный код

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

Оставить отзыв о...

Текущей странице
Скрипты AdWords
Скрипты AdWords