Wednesday, April 10, 2013

Report on Broken Urls In Your Account

Note: If you are looking for a version of this script to run at the MCC level, check out Monitor Broken Links Using MCC Level Scripts.

UPDATED: 2013-05-20: Based on a comment from a reader, the script now only checks active campaigns and adgroups and it also only checks each url once.

UPDATED: 2013-04-28: Based on a comment from a reader, I made some updates to this script which include adding the response code to the email and formatting the results as an attachment.

It happens to the best of us. Sometimes, we remove pages on our site or update links and forget to make the corresponding change our SEM accounts. So tonight I put together a quick script to run through all your ads and keywords and create an email report with any of them that return a 404 Not Found or a 500 Server Error response code. You can easily add more error codes to check for by adding them to the BAD_CODES array at the beginning of the script.

Thanks,
Russ

/****************************
* Find Broken Urls In Your Account
* Version 1.1
* ChangeLog v1.1
*  - Updated to only see Text Ads
* Created By: Russ Savage
* FreeAdWordsScripts.com
****************************/
function main() {
  // You can add more if you want: http://goo.gl/VhIX
  var BAD_CODES = [404,500];
  var TO = ['email@example.com'/*,'email_address_2@example.com'*/];
  var SUBJECT = 'Broken Url Report - ' + _getDateString();
  var HTTP_OPTIONS = {
    muteHttpExceptions:true
  };
   
  //Let's look at ads and keywords for urls
  var iters = [
    //For Ad Level Urls
    AdWordsApp.ads()
      .withCondition("Status = 'ENABLED'")
      .withCondition("AdGroupStatus = 'ENABLED'")
      .withCondition("CampaignStatus = 'ENABLED'")
      .withCondition("Type = 'TEXT_AD'")
      .get(),
    //For Keyword Level Urls
    AdWordsApp.keywords()
      .withCondition("Status = 'ENABLED'")
      .withCondition("DestinationUrl != ''")
      .withCondition("AdGroupStatus = 'ENABLED'")
      .withCondition("CampaignStatus = 'ENABLED'")
      .get()
    ];
  
  var already_checked = {}; 
  var bad_entities = [];
  for(var x in iters) {
    var iter = iters[x];
    while(iter.hasNext()) {
      var entity = iter.next();
      if(entity.getDestinationUrl() == null) { continue; }
      var url = entity.getDestinationUrl();
      if(url.indexOf('{') >= 0) {
        //Let's remove the value track parameters
        url = url.replace(/\{[0-9a-zA-Z]+\}/g,'');
      }
      if(already_checked[url]) { continue; }
      var response_code;
      try {
        Logger.log("Testing url: "+url);
        response_code = UrlFetchApp.fetch(url, HTTP_OPTIONS).getResponseCode();
      } catch(e) {
        //Something is wrong here, we should know about it.
        bad_entities.push({e : entity, code : -1});
      }
      if(BAD_CODES.indexOf(response_code) >= 0) {
        //This entity has an issue.  Save it for later. 
        bad_entities.push({e : entity, code : response_code});
      }
      already_checked[url] = true;
    }
  }
  var column_names = ['Type','CampaignName','AdGroupName','Id','Headline/KeywordText','ResponseCode','DestUrl'];
  var attachment = column_names.join(",")+"\n";
  for(var i in bad_entities) {
    attachment += _formatResults(bad_entities[i],",");
  }
  if(bad_entities.length > 0) {
    var options = { attachments: [Utilities.newBlob(attachment, 'text/csv', 'bad_urls_'+_getDateString()+'.csv')] };
    var email_body = "There are " + bad_entities.length + " urls that are broken. See attachment for details.";
     
    for(var i in TO) {
      MailApp.sendEmail(TO[i], SUBJECT, email_body, options);
    }
  }  
}
 
//Formats a row of results separated by SEP
function _formatResults(entity,SEP) {
  var e = entity.e;
  if(typeof(e['getHeadline']) != "undefined") {
    //this is an ad entity
    return ["Ad",
            e.getCampaign().getName(),
            e.getAdGroup().getName(),
            e.getId(),
            e.getHeadline(),
            entity.code,
            e.getDestinationUrl()
           ].join(SEP)+"\n";
  } else {
    // and this is a keyword
    return ["Keyword",
            e.getCampaign().getName(),
            e.getAdGroup().getName(),
            e.getId(),
            e.getText(),
            entity.code,
            e.getDestinationUrl()
           ].join(SEP)+"\n";
  }
}
 
//Helper function to format todays date
function _getDateString() {
  return Utilities.formatDate((new Date()), AdWordsApp.currentAccount().getTimeZone(), "yyyy-MM-dd");
}

13 comments:

  1. Hi Russell,
    very useful script.
    I tried to exec but I had this problem on line 26:

    Invalid argument: http://{unescapedlpurl} (line 26)

    How can I solve?
    Thank you so much
    Gigi

    ReplyDelete
    Replies
    1. Hi Gianluigi, I updated the script to be a little more robust and include some logging. Can you try this new version? If you still get the same error, let me know what the url is from the logs and I will try to update the script to handle it.

      Thanks,
      Russ

      Delete
  2. Hi Russell, thanks for the support.
    Now the scripts works!
    Your blog is so awesome!

    Gigi

    ReplyDelete
  3. I have this script in our account. Don't know who has put it there. Probably a long time ago. When I run it as a "preview" get no changes. That is strange because we have a lot of URL's in here and I know some are 404. So my question is; Does this script still work?

    ReplyDelete
  4. Take a look at this site to get a full info on term paper writing.

    ReplyDelete
  5. Thanks for sharing this post. This blog was amazing. I am impressed with your thoughts. I got the best information about this topic here and is very useful for all of us. Please visit Online Shopping Coupons , and I hope you may also like our services.

    ReplyDelete
  6. I am very happy to see this post because it is very useful for me because there is so much information in it. I always like to read quality and I'm happy that I got this thing in your post. Thanks for sharing the best article post. Visit Amazon offers Amazon Coupons Amazon Deals

    ReplyDelete
  7. I have tested this for a specific site and I t honestly works out fine on my end. I hope you continue the good work folks. download stardew valley

    ReplyDelete
  8. Best online deals india ,coupons,free courses,free classes,video classes every about online study, hotel coupon, flight coupons, food offers, please visit Hotels Offers

    ReplyDelete
  9. Online religion research paper writing services are very difficult to complete and many students are always searching for Religion Research Paper Services companies to help them complete their custom religion essay writing services.

    ReplyDelete
  10. Nice Post!!!

    This is really a great article.Thanks for sharing the wonderful information and for more information Visit

    lifestyle and technology
    Health and fitness Benfits
    lifestyle and fashion Benfits
    lifestyle and technology benfits
    Electronics benfits


    Very detailed and informative!!
    Keep sharing...

    ReplyDelete
  11. Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post. hotmail log in

    ReplyDelete
  12. The ultimate goal of online sociology research paper writing services is to provide Sociology Assignment Writing Services and sociology essay writing services since most sociology term paper writing service students lack time to complete their custom sociology coursework writing services.

    ReplyDelete