Хочу быть вверху/внизу/вхххх! Новый, улучшенный скрипт удержания позиции в Google AdWords :)

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

Это для меня не удобно, т.к. часто в аккаунтах для, к примеру, горячей кампании нужна позиция 2.4, а для околоцелевой — 4.5, а для еще одной вообще не нужно удерживание позиции, т.к. там уже идет контроль ставок в зависимости от стоимости конверсии.

Пришлось выдохнуть, сесть и написать что-то контролируемое и универсальное. А потом сделать сразу 2 версии: для обычных аккаунтов и для MCC.

Что делает скрипт?

Скрипт запускается каждые 7 дней и поднимает или опускает ставки для тех ключей, которые «съехали» с нужных вам позиций на основании статистики за последние 7 дней.

А чем тогда он отличается от обычного скрипта?

Тут то мы и дошли до сути. Один раз применив скрипт, вы сможете легко задавать целевые позиции для каждой из кампаний, просто применив к кампании ярлыки «positionControl» (включает скрипт) и, к примеру, «targetPosition2.7» (задает позицию).

А если вы зададите скрипт на уровне MCC (сделал версию и для MCC), то чтобы задать нужную позицию, достаточно будет повесить ярлык «positionControl» на аккаунт + ярлыки на кампанию.

Как установить себе в аккаунт?

1) Скопировать скрипт к себе в аккаунт и настроить на выполнение каждую неделю

Код скрипта приведен внизу статьи.

Создаем новый скрипт AdWords и настраиваем его на выполнение каждую неделю

Создаем новый скрипт AdWords и настраиваем его на выполнение каждую неделю

2) Присваиваем кампаниям, которые нужно контролировать, соответствующие ярлыки

  • Чтобы активировать скрипт: ярлык «positionControl«
  • Чтобы выбрать позицию кампании: «targetPosition{позиция}«. Пример: «targetPosition2.4«
Добавляем ярлыки к нужным поисковым кампаниям для активации скрипта AdWords

Добавляем ярлыки к нужным поисковым кампаниям

Это все 🙂

Есть еще из настроек 2 дополнительных необязательных параметра в начале кода скрипта:

  • TOLERANCE — Допустимое отклонение для средней позиции. Т.е. если допустимое отклонение = 0.1 а целевая позиция = 2, то скрипт не затронет ключи с позицией 1.9 и 2.1.
  • BID_ADJUSTMENT_COEFFICIENT — Множитель для изменения ставок. Т.е. если он равно 1.05 то ставки опустятся или поднимутся на 5%.

А если у меня MCC аккаунт и я хочу добавить скрипт один раз, чтобы он применялся ко всем аккаунтам?

Я в конце приложил версию скрипта для MCC. Дополнительно нужно будет задать ярлык «positionControl» еще и для аккаунта, чтобы активировать на нем скрипт.

Скрипт для обычного аккаунта

// Допустимое отклонение для средней позиции. Т.е. если допустимое отклонение = 0.1 а целевая позиция = 2, то скрипт не затронет ключи с позицией 1.9 и 2.1.
var TOLERANCE = 0.1;

// Множитель для изменения ставок. Т.е. если он равно 1.05 то ставки опустятся или поднимутся на 5%.
var BID_ADJUSTMENT_COEFFICIENT = 1.05;

function main() {
  var campaignsWithPosition = AdWordsApp.campaigns().withCondition("LabelNames CONTAINS_ANY ['positionControl']").get();
  while (campaignsWithPosition.hasNext()) {
    var campaign = campaignsWithPosition.next();
    var targetPositionLabel = campaign.labels().withCondition("LabelName STARTS_WITH_IGNORE_CASE 'targetPosition'").get().next().getName();
    var targetPosition = parseFloat(targetPositionLabel.replace(/[^\d.-]/g, ''));
    Logger.log(campaign.getName() + ' - target posinion: ' + targetPosition);
    raiseKeywordBids(campaign, targetPosition);
    lowerKeywordBids(campaign, targetPosition);
  }
}

function raiseKeywordBids(campaign, targetPosition) {
  var keywordsToRaise = campaign.keywords()
    .withCondition("Status = ENABLED")
    .withCondition("AveragePosition > " + (targetPosition + TOLERANCE))
    .orderBy("AveragePosition ASC")
    .forDateRange("LAST_7_DAYS")
    .get();

  while (keywordsToRaise.hasNext()) {
    var keyword = keywordsToRaise.next();
    keyword.setMaxCpc(keyword.getMaxCpc() * BID_ADJUSTMENT_COEFFICIENT);
  }
}

function lowerKeywordBids(campaign, targetPosition) {
  var keywordsToLower = campaign.keywords()
    .withCondition("Ctr > 0.01")
    .withCondition("AveragePosition < " + (targetPosition - TOLERANCE))
    .withCondition("Status = ENABLED")
    .orderBy("AveragePosition DESC")
    .forDateRange("LAST_7_DAYS")
    .get();


  while (keywordsToLower.hasNext()) {
    var keyword = keywordsToLower.next();
    keyword.setMaxCpc(keyword.getMaxCpc() / BID_ADJUSTMENT_COEFFICIENT);
  }
}

Скрипт для MCC

// Допустимое отклонение для средней позиции. Т.е. если допустимое отклонение = 0.1 а целевая позиция = 2, то скрипт не затронет ключи с позицией 1.9 и 2.1.
var TOLERANCE = 0.1;

// Множитель для изменения ставок. Т.е. если он равно 1.05 то ставки опустятся или поднимутся на 5%.
var BID_ADJUSTMENT_COEFFICIENT = 1.05;

function main() {
  MccApp.accountLabels().withCondition("Name = 'positionControl'").get().next().accounts().executeInParallel('accountBids');
}

function accountBids() {
  var campaignsWithPosition = AdWordsApp.campaigns().withCondition("LabelNames CONTAINS_ANY ['positionControl']").get();
  while (campaignsWithPosition.hasNext()) {
    var campaign = campaignsWithPosition.next();
    var targetPositionLabel = campaign.labels().withCondition("LabelName STARTS_WITH_IGNORE_CASE 'targetPosition'").get().next().getName();
    var targetPosition = parseFloat(targetPositionLabel.replace(/[^\d.-]/g, ''));
    Logger.log(campaign.getName() + ' - target posinion: ' + targetPosition);
    raiseKeywordBids(campaign, targetPosition);
    lowerKeywordBids(campaign, targetPosition);
  }
}

function raiseKeywordBids(campaign, targetPosition) {
  var keywordsToRaise = campaign.keywords()
    .withCondition("Status = ENABLED")
    .withCondition("AveragePosition > " + (targetPosition + TOLERANCE))
    .orderBy("AveragePosition ASC")
    .forDateRange("LAST_7_DAYS")
    .get();

  while (keywordsToRaise.hasNext()) {
    var keyword = keywordsToRaise.next();
    keyword.setMaxCpc(keyword.getMaxCpc() * BID_ADJUSTMENT_COEFFICIENT);
  }
}

function lowerKeywordBids(campaign, targetPosition) {
  var keywordsToLower = campaign.keywords()
    .withCondition("Ctr > 0.01")
    .withCondition("AveragePosition < " + (targetPosition - TOLERANCE))
    .withCondition("Status = ENABLED")
    .orderBy("AveragePosition DESC")
    .forDateRange("LAST_7_DAYS")
    .get();


  while (keywordsToLower.hasNext()) {
    var keyword = keywordsToLower.next();
    keyword.setMaxCpc(keyword.getMaxCpc() / BID_ADJUSTMENT_COEFFICIENT);
  }
}

Если у вас есть вопрос, идея или предложение, пишите в комментариях!

UPD 9.02.2016: Важно! В скрипте была ошибка, и он некорректно работал с 2 и более кампаниями. Обновите, пожалуйста, скрипт до текущей версии. Отдельное спасибо Артему Шевченко, который не только нашел баг, но и исправил его!

Алексей Ярошенко

Интернет-маркетолог. Сертифицированный специалист по Google AdWords, Google Analytics и Яндекс.Директ. Сертифицированный тренер Google в Беларуси.