Using Hosted JSON-LD Files as applications/ld+json Scripts for SEO

Sometimes it’s just easier to separate concerns. Just like how stylesheets and .js scripts separate the form and function of the page from the presentation of the page, the same can be done with the JSON-LD schematic markup / structured data of the page. This example shows how you can add structured data for SEO using Javascript which in many cases may prove to be much easier than messing around with your server side code or CMS.

The following Javascript script shows how you can load a stored .jsonld file from your server onto your page as an application/ld+json script tag. Just add it to your page to add hosted JSON-LD files to your page.

How to Add JSON-LD Markup with Javascript

The code below does the following four steps.

  1. The js makes a call to the local .jsonld file
  2. When the file is returned, an application/ld+json script tag is created
  3. The contents of the .jsonld file is inserted as the contents of the script tag
  4. The tag data is ready to be consumed by other applications

The script uses jQuery but the same could be achieved with plain js or any other library/framework of choice. This code can also be added by a tag management system such as Google Tag Manager.

 <script>
   // Add a schema tag to your
   $.getJSON( "/your-schema-file.jsonld", function( data ) {
     $( "<script/>", {
       "type": "application/ld+json",
       "html": JSON.stringify(data)
     }).appendTo( "head" );
   });
 </script>

Does Google Think its Valid Structured Data?

Yes. See this demo for a live working example or go straight to Google’s Structured Data Testing Tool to see the valid results of the demo. Other crawlers may not recognize the script because the script is rendered to the page using Javascript. Therefore the crawler must be able to run javascript which is not all that common.

Creating .jsonld Files

To learn about every single minute detail of creating .jsonld files see this spec about syntax. But essentially, .jsonld files are no different syntactically than JSON files. It is only the specific way that the JSON-LD files signify entities that differs from JSON.

If you need to create multiple JSON-LD files, checkout this Bulk JSON-LD Generator for Google Sheets.

I hope you find this useful. I would love to hear your thoughts in the comments.

First, Learn The Language

The following is an adaptation of the speech I gave at Hong Kong Toastmasters International speech competition. Thought is was interesting so I decided to post it.

Do you remember your first day of school? How about your first time away from you parents or your first time out of the country. Do you remember your first day at a new job or the first day of being a parent. Do you remember how anxious you felt about the unfamiliarity?

We’ve all been in situations like this and looked out at an uncertain future and not known where to start. I’ve found myself in situations like this a lot. It’s almost like I have crazy desire to put myself in these situations.

I’ve found that all of these types of challenges have a one thing in common: you will have to navigate new communities. And despite the difficulty of theses challenges it is possible to become fluent in a community if you can learn the language of that community.

Learning the language of the community makes everything possible. It allows you to understand the community, learn from the community, and express yourself as part of the community.  So if there is one thing that you must do to become fluent in any new community, you must first, learn the language.

Read More

How to Opt-Out of Optimizely (cdn.optimizely.com) in One Click

What does “waiting for ‘cdn.optimizely.com’ mean?

In short, ‘cdn’ means Content Distribution Network and Optimizely is a service that provides A/B Testing for websites. Optimizely makes A/B testing possible by swapping images or changing the structure or style of a web page. To do this, it has to load additional instruction on to the web page being tested.

The reason you are seeing “waiting for cdn.optimizely.com” as you are trying to load a site is most likely because the network you are using is somewhat slow. It just happens to be Optimizely information (likely an image page content for the A/B test) that is coming across the network while you are waiting on a slow network connection.

How to Opt-Out of Optimizely in One Click


The quick solution is to create a bookmarklet to opt out of Optimizely for any page that you don’t want Optimizely to load on. To do this:

  • Create a new bookmark in your browser
  • Instead of adding in a URL add the following:
javascript:(function(){window.location += '?optimizely_opt_out=true'}())
  • click the bookmarklet when loading sites that are using Optimizely.

Done! You’ve successfully opted out of Optimizely. You should no longer have to wait on cdn.optimizely.com for that page. This should remain in effect until you clear that site’s cookies.

Optimizely is not Bad!

(In fact is pretty awesome)

The reason I wrote this is because a friend tweeted his frustration about waiting on “cdn.optimizely.com.” The unfortunate part is that, while Optimizely appears to be the culprit of a slow-loading web page, it’s actually far more likely that a slow network connection is to blame.

You probably like Optmizely but you just didn’t know it. Or until now, you didn’t even know about it. Optimizely is used for A/B testing on tons of sites that you visit, from cnn.com to ehow.com. A/B testing is done to improve sites and provide a better user experience for people like you. And 99.999% of the time you don’t notice it because it is making your life better. Only in this rare occasion is it bothering you. (And it’s because of your network)

How The Bookmarklet Works


The bookmarklet issues some instructions, coded into javascript, to the browser.

javascript:(function(){window.location += '?optimizely_opt_out=true'}())

This basically says the following:

“Here comes a javascript function”

javascript:(function(){

“Take the current URL (aka window.location) and append to it the parameter to opt out of Optimizely.” This is explained further on www.optimizely.com/opt_out.

window.location += '?optimizely_opt_out=true'

“Do these instructions! When the URL is changed, the browser reloads the page with the opt out parameter. This tells Optimizely that no tests should be run on the page and should not load any additional images or information on to the page.” (And you won’t have to wait for it)

}())


I hope this works out for you. Just remember, you don’t hate Optimizely, you hate slow internet connections!

Learn JavaScript, HTML and CSS for Digital Marketing | $10k Tech Skills 1/4

This is part one of four in the $10k Technical Skills for Digital Marketing series. Being able to code JavaScript, HTML and CSS are the technical skills that enable you to design the presentation and experience of your marketing messaging. JavaScript will also take you much further. These skills will really increase your market value if you are interested in conversion rate optimization, web analytics, email marketing, PPC or SEO. See how these skills are useful and how to learn them.

Learn JavaScript. Love JavaScript.

JavaScript was the first technical skill and first programming language I really learned and it turned out to be one of the greatest gifts I have ever given myself. JavaScript is arguably the most frequently used, extensible and most valuable tool for digital marketing. It broadens my capabilities, it increases the speed of my work and it adds value to the work I do. How many skills can you offer to an employer (or yourself) that can make that claim?

JavaScript Skills Trends

Let me substantiate the three claims I just made:

JavaScript Adds Value

JavaScript adds value in the form of more and better data. JavaScript is what enables on-page Web analytics data collection. Anything beyond standard pageview tracking such as Google Analytics custom events, dimensions, metrics or product data demands custom JavaScript code.

In digital marketing, better data enables better performance. With a basic understanding of how JavaScript works, you can communicate clearly with developers how you want to collect the data that you need to improve marketing decisions. With JavaScript coding capabilities you can employ Google Tag Manager and handle the custom tracking instrumentation yourself.

JavaScript Broadens Capabilities

JavaScript is used everywhere! Web Analytics data collection was the original reason for marketers to learn JavaScript but now, thanks in large part to Google, JavaScript can be used to automate tasks from email marketing reporting with Google Spreadsheet to PPC bidding and account maintenance with Google Adwords Scripts.

Finally, the application of JavaScript that has the most potential is UX testing and optimization. JavaScript is what testing platforms like Optimizely use to transform a page into different variations of an A/B test. Along with web analytics tracking, this capability offers enormous value and will certainly continue to do so into the future.

JavaScript Increases Speed Through Automation

JavaScript can be used to program repetitive tasks. Automation makes you fast and enables you to work a larger scale. From simple tasks like finding information on a page using a bookmarklet or Chrome Extension to larger jobs like crawling sites and automating task with PhantomJS.

Better, faster, stronger. See why I love it? In addition to the practical benefits, learning and practicing JavaScript is really fun and will introduce a very cool and progressive community. The last bonus about learning JS is that since Node and MongoDB taken hold, it looks like JS is going to be sticking around for a while.

Read and Write HTML and “Get” CSS

HTML is an easy one. Seriously.

HTML literacy is probably the skill that translates to quantifiable value in the shortest amount of time. HTML takes little time to learn, is relatively easy to become proficient with and there are many opportunities to use the skill. It is everywhere! Take, for instance, an organization where there is little existing HTML literacy, you can step in, change and remove ancient images on website’s rotating marquee and Boom!, digital facelift and decreased page load time! Your boss, your site’s visitors, and Google will thank you.

Even if you just become comfortable enough with HTML to be able to visually parse the source code of a webpage, you will have the ability to identify issues and understand their causes. This skill is especially valuable for Search Engine Optimization.

HTML5 Skills Trends

Technical On-Page SEO

Future-facing SEO, along with common meta-tags, integrates structured data such as Schema.org and JSON-LD requires specific syntax to have their intended affect. Page markup can also affect search engine crawlability, page load times, and cross browser compatibility. In this way, valid HTML affects search engine performance and user experience.

HTML literacy also demonstrates its value when implementing analytics or remarketing tags. The code markup and location of the code on the page must be accurate to properly send data to analytics platforms. Being able to debug implementations and communicate with development partners and not fully rely upon them for minor technical support drastically improves the fluidity of technical marketing initiatives and spares you from worrying how or if things will get done.

Email Marketing

Another quick and measurable impact comes in the form of email marketing. You probably already know this but in case you don’t, emails are coded with HTML. You probably also know that email marketing is often one of the most effective digital marketing channels. The ability to test and optimize the look and feel of marketing emails can have a great impact on the effectiveness of the channel and truthfully of the brand’s identity. From simply swapping out images to writing inline CSS and using email platform template tags, the ability to code HTML is vital to a strong email marketing program.

Conversion Rate Optimization

The final use case for HTML and CSS knowledge is one that offers a remarkably high potential value and that is on-page testing and optimization. Conversion optimization tools like Optimizely and Google Content Experiments allow you to add, remove modify the HTML and CSS (styling, location, spacing) or elements on a page to create different experiment variations of the page. Some of the earliest and biggest wins that come from conversion rate optimization experiments are relatively simple CSS changes so having operational knowledge of CSS can translate to significant value rather quickly.

Conversion Rate Optimization Skills Trends

HTML and CSS knowledge can also translate to a sustainable value beyond the operational, nuts and bolts, knowledge. As your conversion rate optimization testing plan develops and experiment possibilities become less immediate, having the knowledge of presently untapped methods of displaying a page or newer HTML technologies will open up new testing possibilities. As long as browsers and HTML standards continue to change (this will always) prove its value.

Learning JavaScript

Learn By Doing

CodeAcademy.com is a great place to start. It offers a great introduction to the basics of the JavaScript language; syntax, data structures, expressions, etc. It also offers an intro a course on jQuery. The jQuery course is offered before JavaScript which seems strange to me as jQuery is built on top of JavaScript. I would strong suggest taking both courses if you want to learn jQuery.

Learning From The Work of Others

Learning JavaScript, HTML, and CSS is unique in that all the code that makes up a web page is accessible to you. You just have to know how to find it. Chrome Developer Tools (don’t be intimidated) offers a ton of useful ways to inspect and learn what is happening on any web page on the Internet. You can inspect and live-edit pages, see what files are coming into the browser across the network and write JavaScript in the context of any web page with the JavaScript Console. This is a very valuable tool and learning it will also teach you a lot about how browsers, the DOM and web pages work.

Automate Something

Google Apps Script offers an easy interface to try your new skills and accomplish some pretty useful things. It is nice because it abstracts away a lot of complicated things and offers a very simple API to Google Spreadsheets, Google Drive and Google Docs. There is also a lot of good documentation for getting started. If you manage PPC, try Google Adwords Scripts. FreeAdwordsScripts.com offers a lot of good code examples and cool ideas to show how to work with the Adwords Script API.

Books to Read

DOM Enlightenment (Free Online): All you could ever want to learn about interacting with the Document Object Model and more. This is a great one to accompany your exploration of Chrome Developer Tools and the JavaScript console.

Object-Oriented JavaScript: Knowing JavaScript prototypal inheritance is one of the big differences between knowing JS and knowing JS. This is a pretty sweet deep dive into the subject.

Secrets of a JavaScript Ninja: This was written by John Resig who created jQuery. Needless to say, there are a ton of clever patterns to take your JS capabilities to the next level.

Google Apps Script: If you are more interested in the Google Apps Script and simpler forms of automation, this book is great. It will introduce you to a lot of server-side concepts. This stuff is great but just be weary, getting too deep into Google Apps Script may prevent you from learning the really powerful server-side programming languages.

Videos to Watch

Videos can be pretty inspiring. YouTube searches for whatever you are learning can be very helpful but a couple videos that I recommend are:

Learning HTML and CSS

Learn By Doing

codecademy.com again. You have to get repetition with the basics and this is a great intro. Get through it and then read a book and start really practicing.

Guru99 has a ton of free resources.

Learn by Editing

  1. Get to know and love your code editor! Download the code editor of your choice. Atom is free and pretty good.
  2. Write some basic web pages and learn how to use scripts and link style sheets to your web page. Reference w3schools.com and look at the source code of existing pages for reference. GitHub.com has some nice clean source code. (You will also want to get to know GitHub anyway)
  3. Learn some tools. HTML5 Boilerplate is a great place to start with solid web standards and learning Twitter Bootstrap CSS framework will almost certainly come in handy.

Books to Read

HTML5 for Web Designers is great if you want a good basic intro. It will tell you what you need to know but no necessarily how to do it. This book is a must if you are going to be using Optimizely for testing. http://www.abookapart.com/products/html5-for-web-designers

HTML5 & CSS: Learn to Design and Build Websites is an intro to the medium and teaches how to use it at the same time. This is a great book to read in conjunction with step 2 above.

Now go make something awesome! Or rather learn how to make something awesome and keep practicing until you do. These front-end skills will take you a long way and make you very valuable. Check out the rest of the series to learn more about the Back End and Applications, API’s and Web Scraping and Technical Resources and How to Use Them.

Read the rest of the $10k Technical Skills for Digital Marketing or…

Get notified when each posts is released!

Solving Google Tag Manager Race Conditions with eventCallback

Google Tag Manager is a great solution for implementing Web analytics on AJAX-heavy apps. But at times it may seem like it adds more complexity than it relieves. Synchronizing data and events in the dataLayer is an example of this. Sometimes you will want to fire a tag that aims to send data that will show up in the dataLayer after an AJAX call and because you don’t have any guarantee about the timing of this AJAX call you may run into a bit of a race condition.

Fire Events With Data

In the world of javascript you might rely on a call back function to solve this problem. This same idea works with Google Tag Manager, but it has its own way of going about it. The Google Tag Manager solution to this type of problem is to push an event to the dataLayer with the new AJAX delivered data and then set firing rules for any beacons that depend on that information to said event. For instance:

 

 dataLayer.push({
  "newDataAboutX" : {
    "thing1" : "xyz",
    "thing2" : 12
  },
  "event" : "dataAboutXReceived"
});
Then you would set all beacons that require data about X to fire when:
 
{{event}} Equals dataAboutXReceived
 
You can then use dataLayer variables, {{newDataAboutX.thing1}} and  {{newDataAboutX.thing2}} in any beacons that fire on dataAboutXReceived and be sure that they are available.  *A note about accessing dataLayer variables: You can access nested dataLayer variables with dot notation. This also extends to arrays. (for example: myDataLayerArray.3).

Google Tag Manager ‘eventCallback’ Function

If that isn’t enough, Google Tag Manager offers an ‘eventCallback’ function for any object that is pushed to the dataLayer. This is a callback function that is called once all tags that are triggered by this rule are fired. This is often used to navigate to another page after capturing data about the event that would normally cause a URL change. ie: outbound link clicks, navigation clicks or Enhanced Ecommerce  promotion clicks, product listing clicks and product adds to cart.
For example:

 

  dataLayer.push({
    'event':'productClick',
    'ecommerce':{
      'click':{
        'actionField':{'list':'Search Results'}, 
        'products':[{
          'name': productObj.name,               
          'id': productObj.id,
          'price': productObj.price,
          'brand': productObj.brand,
          'category': productObj.cat,
          'variant': productObj.variant
         }]
       }
     },
     'eventCallback':function(){
       document.location = productObj.url
     }
  });

Automate Mobile Preferred Ad Creation with Adwords Scripts

Scripts Save Lives

I love algorithms and you should too. They provide simple consistency to life like no calendar, routine or habit ever could.  They do exactly what you tell them to do and they do it fast, and most beautiful of all, they make life automatic. (sigh of contentment)

I also love javascript but sadly, there are not a lot of places where javascript and algorithms intersect. Scripts for Adwords is one of those happy unions and this delicious union of medium and method has a little cherry on top called automation. Ain’t it sweet!

Adwords Scripts are great for automating reporting, pulling info from other API’s into Adwords and routine account maintenance. The idea for this one was brought up to me by my Google Adwords Rep. Scott, who it turns out, is rad. He called me up one day mentioning how we could optimize one of my accounts. (To be read: “make more money selling ads for Google.”) He suggested that we add mobile preferred ads to all my adgroups with a click-to-call extension, suggesting that this could potentially increase conversion rates from mobile users who are better at calling then poking their screen.

“Lets try it!” I said then thought, “How can I automate this?”

As it turns out, its not fully automatable, as the Adwords Script API does not allow for extensions to be added to ads in the ad creation process. But we can automate our work most of the way there:

How it Works

This script mirrors the process that I went through with my Adwords rep:

  • Select the ad with highest click through rate in its adgroup
  • Copy the headline and URL’s for the selected ad
  • Make a copy with a historically successful call-to-action
  • Make a copy with a mobile optimized call-to-action
  • Set this ad to be mobile-preferred.

But instead of doing this one by one or in a spreadsheet, the script iterates through all adgroups in a the account, and makes the changes with one click. (Now you get why I love algorithms?)

There is one last manual step though. As I mentioned before, Scripts won’t allow for adding extensions or labels in the ad creation process. This means that you will have to go into the Adwords interface, create your click-to-call ad extension and apply it to all your ad groups. To be safe make sure that the call-to-click extension applies only to mobile ad extensions.

So here is the script the script can also be found on my github.

function main() {
  
  //set the following variables to customize the script to your account 
  
  var IMPRESSIONS_THRESHOLD = 100;       // min. impressions an ad needs to have to be considered
  var DATE_RANGE = "LAST_30_DAYS";       // time frame for impression threshold 
  var ADGROUP_NAME_CONTAINS = 'something';   // word or phrase that eligible adgroup name must contain
  
  var DESC_LINE_1 = "Free Shipping and Free Returns!";   // description line 1 (end with punctuation)
  var CTA_CONTROL = "Shop Latest Cool Styles Today";      // a historically succesful CTA for line 2
  var CTA_MOBILE = "Call Now To Place Your Order";       // new mobilized CTA to test for line 2
      
  // select adgroups that meet criteria defined above
  
  var adGroupSelector = AdWordsApp
  .adGroups()
  .withCondition("Status = ENABLED")
  .withCondition("CampaignName CONTAINS_IGNORE_CASE " + "'" + ADGROUP_NAME_CONTAINS + "'")
  
  var adGroupIterator = adGroupSelector.get(); 
  
  // iterate through all selected adgroups
  
  while (adGroupIterator.hasNext()) {
     
    var adGroup = adGroupIterator.next();
    
    var headline;
    var displayURL;
    var destURL;
    var optArgs = {
        isMobilePreferred: true
    };
    
    // select enabled ads that meet predifined criteria
    // ad with best ctr for each group will be copied
    
    var adSelector = adGroup.ads()
    .forDateRange(DATE_RANGE)
    .withCondition("Status = ENABLED")
    .withCondition("Impressions > " + IMPRESSIONS_THRESHOLD)
    .orderBy("Ctr DESC");    
    
    // this iterator does not really iterate, instead
    // it orders by CTR and selects ad with highest CTR
    
    var adIterator = adSelector.get();  
    while (adIterator.hasNext()) {
      var ad = adIterator.next();
      var stats= ad.getStatsFor(DATE_RANGE); 
      
      // headline and URLS are selected from ad
      
      headline = ad.getHeadline();     
      displayUrl = ad.getDisplayUrl();
      destinationUrl = ad.getDestinationUrl();
      Logger.log(headline +": " + stats.getCtr())
      break;     
    }
    
    // and are copied along with pre-defined description line
    // to create to versions of the mobile-prefered ad
    
    adGroup.createTextAd(
      headline,
      DESC_LINE_1,
      CTA_CONTROL,
      displayUrl,
      destinationUrl,
      optArgs
    )
  
    adGroup.createTextAd(
      headline,
      DESC_LINE_1,
      CTA_MOBILE,
      displayUrl,
      destinationUrl,
      optArgs
    )
  }
}

 

Automate MailChimp Reporting with Google Spreadsheets

I made it! I am finally a nerd. At the top of the MailChimp API there is a clear disclaimer: “Woah, Nerds Only!” Undeterred, I scrolled on to test my nerdy medal. The following is my account of navigating the well-charted waters of the MailChimp API and a tutorial on how to automate a “BARF” report using Google Apps Scripts and Google Spreadsheets.

First, let me tell you how this started. Reporting in digital marketing can be a lot of work. Automate it. Ok done explaining.

The MailChimp API is a Friendly API

MailChimp’s API is nice and clean with great documentation. It has well-defined endpoints and returns JSON objects. Google Apps Scripts is great for parsing JSON objects thanks to the JSON class made specifically for that.

The problem as I defined it was as follows:

  1. MailChimp API has the data I want.
  2. I have to make a call to API using Apps Script’s UrlFetchApp
  3.  The call has to be authenticated by passing along API key.
  4. First I have to make a call to get all the campaigns/list endpoint to get a list of campaigns’ name/id info.
  5. Then I have to iterate through all the selected campaigns and pass their id to the reports/[whichever-stat-I-want] endpoints to get back each campaign’s stats.
  6. Format that data into an array and write it to the spreadsheet.

The Google Apps Script


Yup, so that’s exactly what I did. The interesting part for me was getting a better understanding of the UrlFetchApp class. I had used it before for getting data from APIs or web pages but only the simple way:

UrlFetchApp.fetch(“whateversiteiwant.com/data-from”)

But Mailchimp’s API asks for more. It asks that all requests are made as POST requests and it asks that the “apikey” and additional parameters be passed as JSON objects rather than a query string like: www.site.com/api?param=value.

This meant using the additional “param” parameter in the UrlFetchApp.fetch() method. I am happy that I got it to work. It’s clear in the code how it is used but I still need to know exactly why and how it works because it’s pretty cool. Expect a blog post on that.

Beyond that, the code is pretty self-explanatory. I commented parts that would be dodgy for Codecademy level folks. (I know. I was there not too long ago.)

Writing the report to a Google Spreadsheet

Check it out. It is explained in the comments.

// campaigns list api endpoint docs: apidocs.mailchimp.com/api/2.0/campaigns/list.php
// reports api endpoint: apidocs.mailchimp.com/api/2.0/reports/summary.php
// GAS docs: developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetch(String,Object)
// mailchimp open tracking calculations: kb.mailchimp.com/article/about-open-tracking
  
// your api key can be found at: admin.mailchimp.com/account/api/
// standard "24 hour format in GMT, eg "2013-12-30 20:30:00" - if this is invalid the whole call fails"
// add formated values for start and end date like: var REPORT_START_DATE = "2013-12-30 20:30:00"

function chimpReport() {
  
  var API_KEY = 'yourapikeygoeshere';
  var REPORT_START_DATE;
  var REPORT_END_DATE;
  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();  
  
  var dc = API_KEY.slice(-3);
  var api = 'https://'+ dc +'.api.mailchimp.com/2.0';
  var campaignList = '/campaigns/list.json';
  var reports = '/reports/summary.json';
  
  // MC api-specific parameters
  var payload = {
    "apikey": API_KEY,
    "sendtime_start": REPORT_START_DATE,
    "sendtime_end": REPORT_END_DATE
  }; 
  
  // GAS specific parameters: 
  var params = {
    "method": "POST",
    "muteHttpExceptions": true,
    "payload": payload
  };
  
  var apiCall = function(endpoint,cid){
    if(cid){
      payload.cid = cid;
    }
    var apiResponse = UrlFetchApp.fetch(api+endpoint, params);
    var json = JSON.parse(apiResponse);
    return json;
    };
  
  var campaigns = apiCall(campaignList);
  var total = campaigns.total;
  var campaignData = campaigns.data;
  
  for (var i=0; i< campaignData.length; i++){
      
    var c = campaignData[i];
    var cid = c.id;
    var title = c.title;
    var subject = c.subject;
    var send_time = c.send_time;
    
    // send_time values are only present for campaigns that have been sent. otherwise set to null.
    // this if statement will only call for report data and write to the spreadsheet, data from sent campaigns.
    
    if (send_time){
      
      var r = apiCall(reports,cid);
      var emails_sent = r.emails_sent;
      var opens = r.opens;
      var unique_opens = r.unique_opens;
      var clicks = r.clicks;
      var unique_clicks = r.unique_clicks;
      var open_rate = (unique_opens / emails_sent).toFixed(4);
      var click_rate = (unique_clicks / emails_sent).toFixed(4);
      
      // the report array is how each row will appear on the spreadsheet
      var report = [send_time, subject, emails_sent, opens, unique_opens, clicks, unique_clicks, open_rate, click_rate];
      
      Logger.log(report);
      
      // note that this method will append to the bottom of the spread sheet wherever that is.
      // to overwrite a specific range use setValues()
      
      sheet.appendRow(report)
    }    
  }
}

All set!? Next step: make a Google Spreadsheet dashboard with Google Analytics data and Google Spreadsheets Sparklines.

Google Result Date Bookmarklet Using “&as_qdr=y15”

I have been goofing around a lot with JavaScript lately. It’s fun to explore because every time I find and open a new door of understanding, there are two more doors to open and explore. I am currently in the room of browser functionality and thats where I found my bookmarklet.

Making a bookmarklet was an easy way to put a bit of code into action without building anything too big. As it turns out, it’s surprisingly useful. If you have ever wondered when a web page was published, it will tell you, (fairly accurately) just that.

A bookmarklet is essentially a bookmark that holds a bit of JavaScript code that a web browser, like Chrome or Firefox, will execute. Just like any bookmark it is a bit of information held within a link. A link is which is just a reference), but instead of referring to a web page, it refers to some instructions coded in JavaScript. The browser knows the code lingo and does exactly what it is instructed to do.

The instructions look like this (Javascript and HTML translated to plain English):

<a href='javascript:

“Hey browser, this looks like its a link, but no, here comes some JavaScript instructions.”

(function(){if(location.hostname === "www.google.com")

“This is the beginning of the Javascript function: IF the user is on google.com…”

{window.location.href=document.URL+"&as_qdr=y15"}

“THEN: take the page the user is on and change it (make it EQUAL to) the page they are on ADD ON ‘as_qdr=y15’.” (That is the instruction for Google to tell you the dates of all the pages on the results page.)

else{alert("This only works on Google Searches")}})()'

“If the person is not on google.com, ELSE pop-up an alert window and tell them the bad news.”

>Google Date Finder</a>

“Finally, end the Javascript code. Specify the text that anchors the link. End the link code.”

When its all done it looks like this:  

<a href='javascript:(function(){if(location.hostname === "www.google.com"){window.location.href=document.URL+"&as_qdr=y15"}else{alert("This only works on Google Searches")}})()'>Google Date Finder</a>

And amounts to this with the super-sexy CSS styled version below:

Google Date FinderGoogle Date Finder

Just drag one of the links into your bookmark bar, make a Google search, click the “Google Date Finder” bookmarklet and Whammy! each one of the links has a date on it.