Code

Coding, Programming & Algorithms, Tips, Tweaks & Hacks
Search

Alexa Rank function in Google Apps Script

Google Apps Script is JavaScript based scripting for many of Google's services, most noteably, Google Spreadsheets, like VB Macros for Excel.
There are some subtilities in JavaScript, like window and document not being defined. Though the scripting is mostly JavaScript, it is not 100% native JavaScript since it runs in an app and not in the browser.
Currently Google Apps Script has a computeHmacSha256Signature() function but Amazon's AWIS requires a SHA-1 key for its signature which can be obtained from jsSHA. I've clipped the jsSHA code from here as its too lengthy. You can download it from sourceforge, copy-paste the code from /src/sha1.js. A small change is required though. Change b64pad="" to b64pad="=".

Google Apps Script
/*
* When defining a local function 'foo' in a closure, at the end, it is declared global by window.foo = foo
* Google Apps Script has window and document undefined
*/
var window = {};

// Amazon Web Information Services
var AWIS =
{
SERVICE_ENDPOINT : 'http://awis.amazonaws.com/?',
ACTION : 'UrlInfo',
RESPONSE_GROUP : 'Rank',
ACCESS_KEY_ID : "your-access-id",
SECRET_ACCESS_KEY : "your-secret-key"
}

/*
* Validate if a string is of proper domain
* @param String domain
* @return Boolean false if invalid, true if valid
* There are many more tests, this one is just to avoid a bad cell-value
*/
function isValidDomain(domain)
{
if (domain.indexOf(".") < 1) return false;
if (domain.indexOf(":") != -1) return false;
return true;
}

/*
* Get just the hostname from a URL
* @param String URL
* @return String hostname
* http://en.wikipedia.org/wiki/URI_scheme#Examples
*/
function getHostname(url)
{
return url.replace(/http(s*):\/\/(.[^/\?]+)(\/*)(.*)$/g, "$2").toLowerCase();
}

/*
* Validate cellvalue to be of a proper domain
* @param String domain cell-value
* @return Integer Alexa Rank
*/
function getAlexaRank(domain)
{
if (!isValidDomain(domain)) return domain + " is not a valid domain";
var hostname = getHostname(domain);

if (AWIS.ACCESS_KEY_ID == "" || AWIS.ACCESS_KEY_ID == "undefined") return "Error : AWS AccessKey not yet set";
if (AWIS.SECRET_ACCESS_KEY == "" || AWIS.SECRET_ACCESS_KEY == "undefined") return "Error : AWS SecretKey not yet set";

var timestamp = generate_timestamp();
var shaObj = new window.jsSHA(AWIS.ACTION + timestamp, 'ASCII');
var signature = shaObj.getHMAC(AWIS.SECRET_ACCESS_KEY, 'ASCII', 'B64');
var awis_url = AWIS.SERVICE_ENDPOINT + "AWSAccessKeyId=" + AWIS.ACCESS_KEY_ID + "&Action=" + AWIS.ACTION + "&ResponseGroup=" + AWIS.RESPONSE_GROUP + "&Timestamp=" + encodeURIComponent(timestamp) + "&Signature=" + encodeURIComponent(signature) + "&Url=" + encodeURIComponent(hostname);

try
{
var response = UrlFetchApp.fetch(awis_url);
}
catch (err)
{
return "Error in URL : " + awis_url;
}

var sXML = response.getContentText();
var oXML = Xml.parse(sXML, false);
var root = oXML.getElement();
var Response = root.getElements("http://awis.amazonaws.com/doc/2005-07-11","Response");
var UrlInfoResult = Response[0].getElements("http://awis.amazonaws.com/doc/2005-07-11","UrlInfoResult");
var Alexa = UrlInfoResult[0].getElements("http://awis.amazonaws.com/doc/2005-07-11","Alexa");
var TrafficData = Alexa[0].getElements("http://awis.amazonaws.com/doc/2005-07-11","TrafficData");
var Rank = TrafficData[0].getElements("http://awis.amazonaws.com/doc/2005-07-11","Rank");
return Rank[0].getText();
}

/*
* Generate Timestamp of current time
* http://www.w3.org/TR/xmlschema-2/#dateTime
* @return String UTC time in yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format
*/
function generate_timestamp()
{
var now = new Date();

var yyyy = now.getUTCFullYear();
var mm = now.getUTCMonth() < 9 ? "0" + (now.getUTCMonth() + 1) : (now.getUTCMonth() + 1);
var dd = now.getUTCDate() < 10 ? "0" + now.getUTCDate() : now.getUTCDate();

var HH = now.getUTCHours() < 10 ? "0" + now.getUTCHours() : now.getUTCHours();
var ii = now.getUTCMinutes() < 10 ? "0" + now.getUTCMinutes() : now.getUTCMinutes();
var ss = now.getUTCSeconds() < 10 ? "0" + now.getUTCSeconds() : now.getUTCSeconds();

return yyyy + "-" + mm + "-" + dd + "T" + HH + ":" + ii + ":" + ss + ".000Z";
}

/*
* Copy /src/sha1.js from jsSHA (http://jssha.sourceforge.net)
* Currently Google Apps Script has a computeHmacSha256Signature() function but Amazon's AWIS requires a SHA-1 key for its signature
* Also, change b64pad="" to b64pad="="
*/
(function(){var charSize=8,b64pad="=",hexCase=0,str2binb=function(a) ... ;window.jsSHA=jsSHA}());
JavaScript
Vanakkam !

0 comments: