контекстная реклама    веб-аналитика    книги    продуктивность    обо мне
2 заметки с тегом

adwords

В 2015 году я написал заметку про сводные отчёты по показателям качества. Она разлетелась по интернету, многие взяли технику на вооружение.
Я автоматизировал создание таких отчётов и написал скрипт. Он забирает данные за 30 дней, экспортирует в Google Docs и отправляет на почту письмо со ссылкой на отчёт.

Итоговый отчёт

Пример в Google Docs.
Листы:
Source — отчёт по ключам с показателями качества и их факторами.
Pivot Table  — служебная сводная табличка.
LowQS — ключевые слова с QS < 4, отсортированные по бюджету.
Percentage — сводные данные по показателям качества на уровне аккаунта.

Что нового

Добавлена разбивка на составляющие показателей качества, можно видеть вес каждого фактора. Возможность забирать эти данные появилась в версии API AdWords v201607. Факторы, определяющие показатель качества:
CreativeQualityScore: качество объявления,
SearchPredictedCtr: ожидаемый ctr.
PostClickQualityScore: качество страницы приземления.
Красным подкрашены показатели ниже среднего.

Как настроить

  1. Добавляем код скрипта в AdWords: Массовые операции → Скрипты → «+Скрипт».
  2. Делаем копию докса, ставим ссылку на копию в верхнем блоге скрипта Settings.
  3. Указываем в Settings почту получателя отчётов.
  4. При желании ставим на расписание.

Текст письма написан на английском, если нужен русский — можно поменять.

Что дальше

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

Скопировать скрипт с Github

В контексте есть очевидные вещи, которые точно идут на пользу: все нужные расширения объявлений, высокий показатель качества, правильная разметка. Ставки или семантика — более сложные области, на которые влияет множество факторов. Расширения — must have.
Я сделал скрипт для AdWords, который проверяет наличие трёх базовых расширений в кампаниях: быстрых ссылок, номеров телефонов и уточнений.
Скрипт проходится по аккаунту и проверяет расширения. В итоге получается табличка с условным форматированием. Красным помечены места, где нет расширений.
Есть версии скрипта для отдельного аккаунта и MCC. Версия для MCC создаёт лист для каждого аккаунта и подсвечивает вкладку красным цветом, если в аккаунте есть проблемы с расширениями. Для больших аккаунтов со 100+ кампаниями скрипт можно ставить на расписание и выполнять раз в 2 недели.
Страница на GitHub.

Скрипт для уровня аккаунта:

var SHEET_URL = ""; //укажите URL Гугл-таблицы
var SHEET_NAME = "Sheet1"; // если нужно, измените имя листа по умолчанию

function main() {

  var sheet = SpreadsheetApp.openByUrl(SHEET_URL).getSheetByName(SHEET_NAME);
  sheet.clearContents();
  sheet.appendRow(['Название кампании', 'Статус', 'Быстрые ссылки', 'Номера телефона', 'Уточнения']);

  var campaignIterator = AdWordsApp.campaigns().get();

  while (campaignIterator.hasNext()) {

    var campaign = campaignIterator.next();

    var campaignStatus = campaign.isEnabled() ? 'Включена' : campaign.isPaused() ? 'На паузе' : 'Удалена';

    var sitelinksIterator = campaign.extensions().sitelinks().get();
    var sitelink;
    if (sitelinksIterator.hasNext()) {
      sitelink = 'есть';
    } else {
      sitelink = 'нет';
    }

    var phoneNumberIterator = campaign.extensions().phoneNumbers().get();
    var phoneNumber;
    if (phoneNumberIterator.hasNext()) {
      phoneNumber = 'есть';
    } else {
      phoneNumber = 'нет';
    }

    var calloutIterator = campaign.extensions().callouts().get();
    var callout;
    if (calloutIterator.hasNext()) {
      callout = 'есть';
    } else {
      callout = 'нет';
    }

    sheet.appendRow([campaign.getName(), campaignStatus, sitelink, phoneNumber, callout]);
  }

  var range = sheet.getRange("C:E");
  var numRows = range.getNumRows();
  var numCols = range.getNumColumns();
  for (var i = 1; i <= numRows; i++) {
    for (var j = 1; j <= numCols; j++) {
      var currentValue = range.getCell(i, j).getValue();
      if (currentValue == "нет") {
        range.getCell(i, j).setBackground("lightcoral");
        sheet.setTabColor("lightcoral");
      }
    }
  }
}

Скрипт для MCC

var SHEET_URL = ""; //укажите URL Гугл-таблицы
var mccAccount = AdWordsApp.currentAccount();

function main() {

  var sheet = SpreadsheetApp.openByUrl(SHEET_URL);

  var accountSelector = MccApp.accounts()
    .withCondition("Impressions > 10")
    .forDateRange("LAST_MONTH")
    .orderBy("Clicks DESC");

  var accountIterator = accountSelector.get();

  while (accountIterator.hasNext()) {
    var account = accountIterator.next();
    var accountName = account.getName();

    MccApp.select(account);

    sheet.insertSheet(accountName);
    var activeSheet = sheet.getActiveSheet();

    var campaignIterator = AdWordsApp.campaigns().get();
    activeSheet.clearContents();
    activeSheet.appendRow(['Название кампании', 'Статус', 'Быстрые ссылки', 'Номера телефона', 'Уточнения']);

    while (campaignIterator.hasNext()) {

      var campaign = campaignIterator.next();

      var campaignStatus = campaign.isEnabled() ? 'Включена' : campaign.isPaused() ? 'На паузе' : 'Удалена';

      var sitelinksIterator = campaign.extensions().sitelinks().get();
      var sitelink;
      if (sitelinksIterator.hasNext()) {
        sitelink = 'есть';
      } else {
        sitelink = 'нет';
      }

      var phoneNumberIterator = campaign.extensions().phoneNumbers().get();
      var phoneNumber;
      if (phoneNumberIterator.hasNext()) {
        phoneNumber = 'есть';
      } else {
        phoneNumber = 'нет';
      }

      var calloutIterator = campaign.extensions().callouts().get();
      var callout;
      if (calloutIterator.hasNext()) {
        callout = 'есть';
      } else {
        callout = 'нет';
      }

      activeSheet.appendRow([campaign.getName(), campaignStatus, sitelink, phoneNumber, callout]);

    }

    var range = sheet.getRange("C:E");
    var numRows = range.getNumRows();
    var numCols = range.getNumColumns();
    for (var i = 1; i <= numRows; i++) {
      for (var j = 1; j <= numCols; j++) {
        var currentValue = range.getCell(i, j).getValue();
        if (currentValue == "нет") {
          range.getCell(i, j).setBackground("lightcoral");
          activeSheet.setTabColor("lightcoral");
        }
      }
    }
  }

}