ТОП 5 скриптів в Google Ads для професіонала

Скрипт – це фрагмент коду на JavaScript, який дозволяє вносити зміни в обліковий запис Google Ads. Якщо ви керуєте великими проектами, скрипти допоможуть заощадити час при масовому редагуванні аккаунта, а також допоможуть звільнити фахівця з контекстної реклами від деяких рутинних завдань.

1. Скрипт для зупинки кампаній на свята

Даний скрипт запуняє кампанії на свята, а також запускає їх на наступний день. В скрипті треба вказати назву ярлика (за замовченням в скрипті вказан ярзик з назвою ‘active’), яка присвоєна кампанії, а також у змінній days_off перелікувати дати святкових днів через кому.

/********************************************************

* Version 1.2

* April 25, 2019

* Created By: Denys German

********************************************************/

var days_off = '28-04-2019,29-04-2019,30-04-2019,01-05-2019,09-05-2019';//задаем даты выходных дней, в которые кампании не должны работать без пробелов в формате dd-mm-yyyy

var labelName = 'active';//ярлык кампаний, к которым будет примеменяться скрипт

var statusSwitcher = 0;




function main() {

  //Подготовка списка дат

  var todayStr = new Date();

  var yesterdayStr = new Date();

  yesterdayStr.setDate(todayStr.getDate() - 1);

  var todayStrFromat = Utilities.formatDate(todayStr, AdsApp.currentAccount().getTimeZone(), 'dd-MM-yyyy');

  var yesterdayStrFromat = Utilities.formatDate(yesterdayStr, AdsApp.currentAccount().getTimeZone(), 'dd-MM-yyyy');

  var dataFormatArr = days_off.split(',');

  //Алгоритм определения того, что делать с кампаниями: включать, выключать, ничего не делать

  for (var i=0; i<dataFormatArr.length; i++)

  {

                if(dataFormatArr[i]==todayStrFromat)

    {

                               statusSwitcher = 1;

                                                break;

    }

    else if(dataFormatArr[i]==yesterdayStrFromat)

                               statusSwitcher = 2;

  }

  //Блок включения/выключения кампаний

  switch (statusSwitcher) {

  case 1:

    pauseCampaign();

    break;

  case 2:

    enableCampaign();

    break;

   default:

    Logger.log('Никаких изменений');

  }

}

//Остановка кампаний

function pauseCampaign() {

var campaignIterator = AdsApp.campaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

var shopingcampaignIterator = AdsApp.shoppingCampaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

var videocampaignIterator = AdsApp.videoCampaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

while(campaignIterator.hasNext()) {

  campaignIterator.next().pause();

}

while(shopingcampaignIterator.hasNext()) {

  shopingcampaignIterator.next().pause();

}

while(videocampaignIterator.hasNext()) {

  videocampaignIterator.next().pause();

}

   Logger.log("Кампании остановлены");

}




//Запуск кампаний

function enableCampaign() {

var campaignIterator = AdsApp.campaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

var shopingcampaignIterator = AdsApp.shoppingCampaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

var videocampaignIterator = AdsApp.videoCampaigns()

  .withCondition("LabelNames CONTAINS_ANY ['" + labelName + "']")

  .get();

while(campaignIterator.hasNext()) {

  campaignIterator.next().enable();

}

while(shopingcampaignIterator.hasNext()) {

  shopingcampaignIterator.next().enable();

}

while(videocampaignIterator.hasNext()) {

  videocampaignIterator.next().enable();

}

    Logger.log("Кампании запущены");

}

 2. Скрипт чистки майданчиків КМС

Часом реклама в КМС показується на майданчиках, які свідомо далекі від тематики рекламної кампанії, наприклад на музичних порталах або на сайтах з рефератами. Даний скрипт робить автоматичну чистку майданчиків зі свідомо не потрібними доменами.

Для роботи зі скриптом слід створити ярлик для медійних кампаній, а також вказати цей ярлик в скрипті. У перерахування доменів можна додавати свої, а також можна виключати доменні зони, наприклад задати ‘ua’. Ще можна задати за який період будуть оброблятися майданчики. За замовчуванням в скрипті встановлений період 7 днів.

Можливі періоди:

LAST_7_DAYS

    LAST_WEEK

    LAST_MONTH

    LAST_14_DAYS

    LAST_30_DAYS

    LAST_BUSINESS_WEEK

    THIS_WEEK_SUN_TODAY

    THIS_WEEK_MON_TODAY

    LAST_WEEK_SUN_SAT

    THIS_MONTH

/*

* Скрипт создан Алексеем Ярошенко.

*/

var exclude = ['pdf','gta', 'dota', 'minecraft', 'resheb','referat','igry', 'igra', 'igri', 'game', 'flash', 'apk', 'android', 'mp3', 'fb2', 'dating','goroskop', 'astro', 'film', 'video', 'movie', 'book', 'download','torrent', 'kino', 'radio', 'weather', 'pesni', 'chords','anekdot', 'zodiak', 'minusovk', 'knig', 'recept', 'recipe','spongebob', 'barbie', 'skyrim', 'ferma', 'dom2', 'mafia','gadani', 'mario', 'epub', '2048', 'dendy', 'sega','zuma','aforizm', 'citat', 'pdf', 'simulat', 'mods', 'play','spintires', 'spin-tires', 'girl', 'boy' ];

var period = 'LAST_7_DAYS';

function main() {

    var periodString = '';

    if (period) {

        periodString = "DURING " + period;

        Logger.log(periodString);

    } else {

        Logger.log('DURING ALL TIME');

    }

    var report = AdWordsApp.report("SELECT Domain, Clicks, Conversions " +

        "FROM AUTOMATIC_PLACEMENTS_PERFORMANCE_REPORT " +

        periodString);

    var rows = report.rows();

    var excludePlacementArray = [];

    while (rows.hasNext()) {

        var row = rows.next();

        var placement = row['Domain'];

        if (containsAny(placement.toString(), exclude) && (row['Conversions'] < 1)) {

            excludePlacementArray[excludePlacementArray.length] = placement.toString();

        }

    }

    addNegativeKeywordToCampaign(excludePlacementArray);

}

function containsAny(str, substrings) {

    for (var i = 0; i != substrings.length; i++) {

        var substring = substrings[i];

        if ((str.indexOf(substring) != -1) && (str.indexOf('mobileapp::') == -1)) {

            return substring;

        }

    }

    return null;

}

function addNegativeKeywordToCampaign(negativePlacements) {

    var campaignIterator = AdWordsApp.campaigns().withCondition("LabelNames CONTAINS_ANY ['НазваниеЯрлыка']").get();

    while (campaignIterator.hasNext()) {

        var campaign = campaignIterator.next();

        negativePlacements.forEach(function (entry) {

            excludePlacement = campaign.display().newPlacementBuilder();

            excludePlacement.withUrl(entry.toString()).exclude();

            Logger.log(entry.toString() + ' - Excluded');

        });
    }
}

 

3. Скрипт утримання позиції

Скрипт запускається кожні 7 днів і підвищує або знижує ставки для тих ключових фраз, які знаходяться вище або нижче від тієї позиції, яку ми задали.

Докладніше про налаштування скрипта можна дізнатися на сайті автора.

//Допустиме відхилення для середньої позиції. Тобто якщо допустиме відхилення = 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);

  }

}

4. Перевитрата бюджету

Іноді Google витрачає грошей на рекламну кампанію більше, ніж фахівець виділяє на неї. Це може призводити до того, що ми не впишемося в місячний бюджет.

Даний скрипт перевіряє роботу всіх кампаній. В скрипті можна задати в процентному співвідношенні допустимі рамки перевищення бюджету. За замовчуванням скрипт зупиняє кампанію в тому випадку, якщо вони на 20% перевищила денний бюджет. Якщо для вас це багато, ви можете змінити параметр allowedOverdeliveryPercentage.

function main() {

  var allowedOverdeliveryPercentage = 0.2; // set percentage as decimal, i.e. 20% should be set as 0.2

  var labelName = "paused by overdelivery checker script"; 

  AdWordsApp.createLabel(labelName, "automatic label needed to reenable campaigns");  

  var campaigns = AdWordsApp.campaigns()

   .withCondition("Status = ENABLED")

   .withCondition("Cost > 0")

   .forDateRange("TODAY");

  var campaignIterator = campaigns.get();

  while (campaignIterator.hasNext()) {

    var campaign = campaignIterator.next();

    var campaignName = campaign.getName();

    var budgetAmount = campaign.getBudget().getAmount();

    var costToday = campaign.getStatsFor("TODAY").getCost();

    if(costToday > budgetAmount * (1 + allowedOverdeliveryPercentage)) {

      Logger.log(campaignName + " has spent " + costToday + " which is more than allowed.");

      campaign.applyLabel(labelName);

      campaign.pause();

    } else {

      Logger.log(campaignName + " has spent " + costToday + " and can continue to run.");

    }

  }

}

5. Скрипт перевірки наявності розширень на рівні кампанії

За замовчунням перевіряється наявність таких розширень: телефонні номери, додаткові посилання, структуровані описи, уточнення.

//Options setcion
var OPTIONS = {
  'REPORT_URL': '', // url of existing report sheet. leave empty string to create new report when script runs
  'LOOKBACK': '', // optional lookback for items selectors that picks non removed items in loookback period. Defolts to 'LAST_7_DAYS'
  'EXTENSIONS': ['sitelinks', 'callouts', 'snippets'], // list of extnesions to check. Defaults to ['sitelinks', 'callouts', 'snippets', 'phoneNumbers']
  'FORCE_CHECK': true // If true will report if adgroup doesn't contain particular extension but it's available at campaign level. Defaults to false
}
function getOptions () {
  var options = {}
  if (OPTIONS.REPORT_URL) {
    try {
      var spreadsheet = SpreadsheetApp.openByUrl(OPTIONS.REPORT_URL)
      } catch (e) {
        Logger.log('Cannot open specified URL %s, will create new spresdsheet', OPTIONS.REPORT_URL)
        var spreadsheet = SpreadsheetApp.create('AdWords Extensions Check')
        Logger.log('New spreadsheet created %s', spreadsheet.getUrl())
      }
  } else {
    var  spreadsheet = SpreadsheetApp.create('AdWords Extensions Check')
    Logger.log('New spreadsheet created %s', spreadsheet.getUrl())
    spreadsheet.getSheets()[0].setName('Extensions check')
  }
  var sheets = spreadsheet.getSheets()
  var sheetNames = sheets.reduce(function (list, sheet) {
    list.push(sheet.getName())
    return list
  }, [])
  if (sheetNames.indexOf('Extensions check') == -1) {
    options.extensionsSheet = spreadsheet.insertSheet('Extensions check')
  } else {
    options.extensionsSheet = spreadsheet.getSheetByName('Extensions check')
  }
  options.lookback = OPTIONS.LOOKBACK || 'LAST_7_DAYS'
  options.extensionsList = OPTIONS.EXTENSIONS || ['sitelinks', 'callouts', 'snippets', 'phoneNumbers']
  
  options.getReportURL = function () {
    return spreadsheet.getUrl()
  }
  
  options.forceCheck = OPTIONS.FORCE_CHECK || false
  return options
}
function checkExtensions (options) {
  var campaigns = AdWordsApp.campaigns()
  .withIds(getSearchCampaignsIds(options))
  .get()
  if (!campaigns.totalNumEntities()) {
    Logger.log('No applicable campaigns found')
    return
  } else {
    var checkItems =  options.extensionsList
    var sheet = options.extensionsSheet.clear().appendRow('Account,Campaign,AdGroup,Extension Status'.split(','))
    var rows = []
    while (campaigns.hasNext()) {
      var campaign = campaigns.next()
      var campaignLevelExtensions = {}
      for (var i = 0; i < checkItems.length; i++) {
        campaignLevelExtensions[checkItems[i]] = campaign.extensions()[checkItems[i]]().get().totalNumEntities()
        if (campaignLevelExtensions[checkItems[i]] == 0 ) {
          // Logger.log('no campaign  level  %s campaign %s', checkItems[i], campaign.getName())
        }
      }
      var adGroups = campaign.adGroups()
      .forDateRange(options.lookback)
      .withCondition("Impressions > 0")
      .withCondition("Status != REMOVED")
      .get()
      var adgroupLevelExtensions = {}
      while (adGroups.hasNext()) {
        var adgroup = adGroups.next()
        var adgroupRow = [AdWordsApp.currentAccount().getName(), campaign.getName(), adgroup.getName()]
        for (var k = 0; k < checkItems.length; k++) {
          var numOfExtensions = adgroup.extensions()[checkItems[k]]().get().totalNumEntities()
          if (options.forceCheck) {
            if (numOfExtensions == 0) {
            rows.push(adgroupRow.concat(['No ' + checkItems[k] + ', ' + campaignLevelExtensions[checkItems[k]] + ' at campaign level']))     
          }
          } 
          else {
          if (numOfExtensions == 0 && campaignLevelExtensions[checkItems[k] == 0]) {
            rows.push(adgroupRow.concat(['No ' + checkItems[k] + ' at campaign and adgroup level']))     
          }
          }
          adgroupLevelExtensions[checkItems[k]] =  0 || adgroupLevelExtensions[checkItems[k]]
          adgroupLevelExtensions[checkItems[k]] +=  numOfExtensions
        }
      }
      // Process campaign summary
      var campaignRow = [AdWordsApp.currentAccount().getName(), campaign.getName(), 'Campaign Level']
      for (var i = 0; i < checkItems.length; i++) {
        if (campaignLevelExtensions[checkItems[i]] + adgroupLevelExtensions[checkItems[i]]== 0) {
          rows.push(campaignRow.concat(['No ' + checkItems[i] + ' at campaign and in any its group' ]))
        }
      }
    }
  sheet.getRange(2,1,rows.length, 4).setValues(rows)
  Logger.log('check results in %s', options.getReportURL())
  }
}
function getSearchCampaignsIds(options) {
  var report = AdWordsApp.report(
    "SELECT CampaignId, CampaignName, AdvertisingChannelType, Impressions " +
    "FROM   CAMPAIGN_PERFORMANCE_REPORT " +
    "WHERE  Impressions > 0 " +
  "AND  AdvertisingChannelType = 'SEARCH' " +
    "DURING " + options.lookback);
  var rows = report.rows()
  var res = []
  while (rows.hasNext()) {
    var row = rows.next()
    res.push(row.CampaignId)
  }
  return res
}
function main() {
  var options = getOptions()
  checkExtensions(options)
}

Висновки

Скрипти Google Ads – це корисний інструмент, який дозволяє автоматизувати рутинні завдання фахівця з контекстної реклами.

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

Якщо вам необхідно налаштувати якісну рекламну кампанію в Google, ви завжди можете скористатися нашою послугою з настройки контекстної реклами.