Vérifier les urls de destinations dans Adwords

Lorsque vos comptes de campagnes commencent à être volumineux, il devient difficile de vérifier toutes vos urls de destinations, une à une. Voici un système qui permet de vérifier si vos urls de destinations contiennent des 404 et cela régulièrement. C’est un peu technique mais plutôt utile. Accrochez-vous c’est parti.

Comment cela fonctionne ?apercu de la feuille de calcul google drive

Le système est divisé en deux éléments. Le premier est sûr le rapport généré via une feuille de calcul sur Google Drive. Ce template va récolter tout les résultats issus du script que vous avez lancé sur votre compte adwords ! Le script quant à lui est exécuté via l’interface adwords.

Le script à exécuter

Tout d’abord le script ne vérifiera pas deux fois les mêmes urls dans la même journée. Une exécution du script vérifiera 800 urls et la limite est de 20 000 urls par jour. Si votre compte contient moins de 800 urls, faites exécuter votre script une fois par jour. Le script va créer un label « link_checked », pour chaque mot clé vérifié, de cette facon les mots clés vérifiés ne le seront pas une deuxième fois. Ce label sera retiré et ajouter tous les jours. Le script ne vérifie que les mots clés qui ont une URL de destination. Si votre URL de destination n’est renseigné qu’au niveau de l’annonce, le mot clé ne sera pas vérifié.

Installation

1. Ouvrez le template dans Google drive

2. Faire un copie de ce template et sauvegardez-le

3. Retournez sur votre compte adwords
– Allez sur Opérations Partagées>Scripts
– Cliquez sur Créer et gérer les scripts créer un script dans adwords
– Créer un nouveau script
– Donnez un nom à votre script (n’importe lequel)
– Copiez et collez le script situé en fin de page
– Remplacer :

var SPREADSHEET_URL = "[YOUR_URL]";
Par
var SPREADSHEET_URL = "https://docs.google.com/...";

– Sauvegardez le script et ensuite fermez-le
– Si besoin programmez la fréquence sur script

Astuces

Lors de l’installation de ce mécanismes j’ai rencontré quelques erreurs :

– Vérifiez bien que l’adresse du compte adwords est propriétaire de la version de la feuille de calcul
– Il a été nécessaire pour ma part de créer le label avant d’exécuter le script. Pour ce faire, sur l’interface Adwords et créez le libellé (labels en anglais) link_checked N’hésitez pas à faire votre retour d’expérience dans les commentaires !

var SPREADSHEET_URL = "[YOUR_URL]";

var LABEL_NAME = "link_checked";

var shelper = new SHelper();
var badUrls = 0;

function main() {
  dealWithFirstRunOfTheDay();
  if (shelper.config.email.length == 0 && shelper.config.emailPreference != "Never") {
    Logger.log("WARNING: no email specified, proceeding...");
  }
  if (!shelper.config.checkAds && !shelper.config.checkKeywords) {
    Logger.log("WARNING: requested no keywords and no ads checking. Exiting.");
    return;
  }
  createLinkCheckerLabel();

  var anythingChanged = shelper.config.checkKeywords && checkUrls(AdWordsApp.keywords());
  anythingChanged = (shelper.config.checkAds && checkUrls(AdWordsApp.ads())) || anythingChanged;

  if (anythingChanged) {
    shelper.flush();
    if (badUrls > 0 && shelper.config.email.length > 0 && shelper.config.emailPreference == "As soon as an error is discovered") {
      var bad = shelper.spreadsheet.getRangeByName("bad").getValue();
      var good = shelper.spreadsheet.getRangeByName("good").getValue();
      sendReportWithErrors(good, bad);
    }
  } else {
    shelper.spreadsheet.getRangeByName("finished").setValue("All done for the day!");
  }
}

function dealWithFirstRunOfTheDay() {
  var date = new Date();
  var lastCheckDate = shelper.dataSheet.getRange(1, 3).getValue();
  if (lastCheckDate.length == 0 || date.getYear() != lastCheckDate.getYear() ||
      date.getMonth() != lastCheckDate.getMonth() || date.getDay() != lastCheckDate.getDay()) {
    // kill the label.
    var labels = AdWordsApp.labels().withCondition("Name='" + LABEL_NAME + "'").get();
    if (labels.hasNext()) {
      labels.next().remove();
    }
    // send out yesterday's report
    if (shelper.config.email.length > 0 && (shelper.config.emailPreference == "Once a day" ||
        shelper.config.emailPreference == "Once a day if there are errors")) {
      var bad = shelper.spreadsheet.getRangeByName("bad").getValue();
      var good = shelper.spreadsheet.getRangeByName("good").getValue();
      if (shelper.config.emailPreference == "Once a day") {
        if (bad == 0) {
          MailApp.sendEmail(shelper.config.email,
              "AdWords Link Checker verified " + good +
              " URLs on account " + AdWordsApp.currentAccount().getCustomerId() + ", all looking good!", "");
        } else {
          sendReportWithErrors(good, bad);
        }
      } else if (shelper.config.emailPreference == "Once a day if there are errors" && bad > 0) {
        sendReportWithErrors(good, bad);
      }
    }
    // reset the spreadsheet
    shelper.spreadsheet.getRangeByName("account_id_dashboard").setValue(AdWordsApp.currentAccount().getCustomerId());
    shelper.spreadsheet.getRangeByName("account_id_report").setValue(AdWordsApp.currentAccount().getCustomerId());
    shelper.spreadsheet.getRangeByName("date").setValue(date);
    shelper.spreadsheet.getRangeByName("finished").setValue("Checking links...");
    shelper.dataSheet.getRange(4, 1, shelper.dataSheet.getMaxRows() - 3, 6).clear();
  }
}

function sendReportWithErrors(good, bad) {
  var emailBody = [];
  emailBody.push("Summary for account " + AdWordsApp.currentAccount().getCustomerId() +
      ": " + good + " good URLs, " + bad + " bad ones\n");
  emailBody.push("Full report available at " + shelper.spreadsheet.getUrl() + "\n");
  shelper.reset();
  var row = shelper.readRow();
  while (row != null && emailBody.length < 200) {
    if (row[1] >= 300) {
      var entityType = row[4].length > 0 ? "Keyword: " : "Ad: ";
      var entityText = row[4].length > 0 ? row[4] : row[5];
      emailBody.push("Campaign: " + row[2] + ", Ad Group: " + row[3] + ", " + entityType + entityText);
      emailBody.push(row[0] + " - " + row[1] + " response code.\n");
    }
    row = shelper.readRow();
  }
  if (emailBody.length >= 200) {
    emailBody.push("Further URLs omitted. Check the report at " + shelper.spreadsheet.getUrl());
  }
  shelper.reset();
  MailApp.sendEmail(shelper.config.email,
    "AdWords Link Checker verified found " + bad +
    " bad URLs on account " + AdWordsApp.currentAccount().getCustomerId() + "",
    emailBody.join("\n"));
}

function checkUrls(selector) {
  var iterator = selector
    .withCondition("DestinationUrl STARTS_WITH_IGNORE_CASE 'h'")
    .withCondition("LabelNames CONTAINS_NONE['" + LABEL_NAME + "']")
    .orderBy("DestinationUrl")
    .withLimit(800)
    .get();
  if (!iterator.hasNext()) {
    return false;
  }
  var lastUrl = "";
  while (iterator.hasNext()) {
    var entity = iterator.next();
    if (entity.getDestinationUrl() != lastUrl) {
      lastUrl = entity.getDestinationUrl();
      var now = new Date().getTime();
      var response = UrlFetchApp.fetch(lastUrl, { muteHttpExceptions: true} );
      var then = new Date().getTime();
      Utilities.sleep(then - now);
      if (response.getResponseCode() < 300) {
        shelper.writeRow(lastUrl, response.getResponseCode());
      } else {
        badUrls ++;
        if (typeof(entity['getHeadline']) != "undefined") {
          var adText = entity.getType() == "TEXT_AD" ?
              entity.getHeadline() + "\n" + entity.getDescription1() + "\n" + entity.getDescription2() :
              entity.getType();
          shelper.writeRow(lastUrl, response.getResponseCode(),
              entity.getCampaign().getName(), entity.getAdGroup().getName(), null, adText);
        } else {
          shelper.writeRow(lastUrl, response.getResponseCode(),
              entity.getCampaign().getName(), entity.getAdGroup().getName(), entity.getText());
        }
      }
    }
    entity.applyLabel(LABEL_NAME);
  }
  return true;
}

function createLinkCheckerLabel() {
  var labels = AdWordsApp.labels().withCondition("Name='" + LABEL_NAME + "'").get();
  if (!labels.hasNext()) {
    AdWordsApp.createLabel(LABEL_NAME, "Managed by Link Checker, please don't modify!", "#60e020");
  }
}

// Spreadsheet helper
function SHelper() {
  this.MAX_ROWS = 20000;
  this.BATCH_SIZE = 50;
  this.spreadsheet = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
  this.dataSheet = this.spreadsheet.getSheets()[1];
  this.config = {
    checkAds: this.spreadsheet.getRangeByName("check_ads").getValue() == "Yes",
    checkKeywords: this.spreadsheet.getRangeByName("check_keywords").getValue() == "Yes",
    email: this.spreadsheet.getRangeByName("email_address").getValue(),
    emailPreference: this.spreadsheet.getRangeByName("email_preference").getValue(),
  }
  this.globalRow = 4;
  this.cells = null;
  this.localRow = 0;

  this.reset = function() {
    this.globalRow = 4;
    this.cells = null;
    this.localRow = 0;
  };
  this.readRow = function() {
    initCells(this);
    if (this.localRow == this.cells.length) {
      this.globalRow += this.cells.length;
      if (this.globalRow >= this.dataSheet.getMaxRows()) {
        return null;
      }
      this.cells = this.dataSheet.getRange(this.globalRow, 2, this.BATCH_SIZE, 6).getValues();
      this.localRow = 0;
    }
    if (this.cells[this.localRow][0].length > 0) {
      return this.cells[this.localRow++];
    } else {
      return null;
    }
  };
  this.writeRow = function() {
    fetchCells(this);
    for (var i = 0; i < arguments.length; i ++) {
      this.cells[this.localRow][i] = arguments[i];
    }
  };
  this.flush = function() {
    if (this.cells) {
      this.dataSheet.getRange(this.globalRow, 2, this.cells.length, 6).setValues(this.cells);
      this.dataSheet.getRange(1, 1).copyFormatToRange(this.dataSheet, 3, 3, this.globalRow, this.globalRow + this.cells.length);
    }
  };
  function initCells(instance) {
    if (instance.cells == null) {
      instance.globalRow = 4;
      instance.cells = instance.dataSheet.getRange(instance.globalRow, 2, instance.BATCH_SIZE, 6).getValues();
      instance.localRow = 0;
    }
  }
  function fetchCells(instance) {
    initCells(instance);
    while (!findEmptyRow(instance) && instance.globalRow < instance.MAX_ROWS) {
      if (instance.dataSheet.getMaxRows() < instance.globalRow + this.BATCH_SIZE) {
        instance.dataSheet.insertRowsAfter(instance.dataSheet.getMaxRows(), instance.BATCH_SIZE);
      }
      instance.flush();
      instance.globalRow += instance.cells.length;
      instance.cells = instance.dataSheet.getRange(instance.globalRow, 2, instance.BATCH_SIZE, 6).getValues();
      instance.localRow = 0;
    }
    if (instance.globalRow >= instance.MAX_ROWS) {
      Logger.log("WARNING: maximum length of the spreadsheet exceeded. Exiting.");
      throw "";
    }
  }
  function findEmptyRow(instance) {
    for (; instance.localRow < instance.cells.length && !(instance.cells[instance.localRow][0] == null ||
        instance.cells[instance.localRow][0].length == 0); instance.localRow++);
    return instance.localRow < instance.cells.length;
  }
}

Source

Nicolas BYKOFF
Nicolas BYKOFF

A propos de Nicolas BYKOFF

Search Specialist chez Sanoma Digital Netherlands, je suis aussi un serial gamer : minecraft, backgammon, Magic the gathering etc... Vous pouvez aussi retrouver mes articles sur Business Actor ou encore Serial Gamer
Loading Facebook Comments ...