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");
}

28 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
  13. To seek the best Healthcare Assignment Writing Services for those studying healthcare coursework writing services, it is important to hire an award winning healthcare essay writing service company.

    ReplyDelete
  14. To seek the best Healthcare Assignment Writing Services for those studying healthcare coursework writing services, it is important to hire an award winning healthcare essay writing service company.

    ReplyDelete
  15. Good post but I was wondering if you could write a litte more on this subject? I’d be very thankful if you could elaborate a little bit further. Appreciate it! buy 20 instagram likes uk

    ReplyDelete
  16. Great article Lot's of information to Read...Great Man Keep Posting and update to People..Thanks read more

    ReplyDelete
  17. Thank you for your post, I look for such article along time, today i find it finally. this post give me lots of advise it is very useful for me. Ellovi natural skincare products

    ReplyDelete
  18. Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. Brian Gets Cars

    ReplyDelete
  19. It’s actually a great and also handy section of details. I am just fulfilled that you simply contributed this helpful info along with us.. Be sure to keep us knowledgeable similar to this. Thank you for expressing.
    cash for cars ipswich
    cash for cars toowoomba

    ReplyDelete
  20. Great remarkable issues here. I’m very glad to look your article. Thanks a lot and I am having a look forward to touch you. Will you please drop me a mail?
    cash for cars north brisbane
    car wreckers brisbane

    ReplyDelete
  21. Thank you very much for the information provided! I was looking for this data for a long time, but I was not able to find the trusted source.. I’ve learn several good stuff here. Definitely price bookmarking for revisiting. I wonder how so much attempt you place sex make this kind of fantastic informative web site.
    car removal brisbane
    cash for cars rockhampton

    ReplyDelete
  22. Fantastic goods from you, man. I've understand your stuff previous to and you are just extremely fantastic. I really like what you have acquired here, really like what you are stating and the way in which you say it. You make it entertaining and you still take care of to keep it sensitive. I can't wait to read far more from you. This is really a tremendous site.
    cash for cars brisbane
    cash for scrap cars gold coast

    ReplyDelete