Since the properties service has a script and a user level store, and although it’s obvious, it occurred to me that this could be used to know whether someone had used a library before. If they had, there would be a user level store – if not – they must be new.
So I put together this library that you can use for tracking usage (it can of course also track its own usage). Here’s the key, or you can copy the code at the end of this post.
MwbZ76EQqpFNfqh-XUl5Jxqi_d-phDA33
How to use
In the script that needs tracking, then do this. It returns the usage stats if you want to look at them
// update usage of this script Logger.log (GoingGasLib.PropUtils.updateUsage( PropertiesService.getScriptProperties(), PropertiesService.getUserProperties() ));
If you need to get overall usage stats, then you can also get them with this
Logger.log(GoingGasLib.PropUtils.getUsage( PropertiesService.getScriptProperties() ));
If you want to track a library, I would recommend that you also allow opting-in rather than just tracking without asking. If you are using my version of this library and want to opt in to my tracking, then put this in your script too. The default is that no tracking is done.
GoingGasLib.PropUtils.initializeUsage();
What data is stored
Here’s what will be in your script store
{ "visits": 5, "averageTimeBetweenVisits": 283606.2, "uniqueVisitors": 2, "dateOfLastVisit": 1453893328519 }
And here’s what’s in each users store
{ "visits": 3, "id": "4386370c-f222-4c57-9442-557d4c79c0d7", "averageTimeBetweenVisits": 45053.333333333336, "dateOfLastVisit": 1453892045537 }
The Id
So now every unique user will have an id you can use – for example – now I can improve Universal analytics measurement protocol for your GAS libraries by using this id to submit data against. It has the benefit of not being traceable to a specific person since no identifiable information is stored, but yet is unique and reusable, so will be useful in its own right – whether or not you use this for tracking usage.
The code
Here’s the function code.
/** * libary for use with Going Gas Videos * PropUtils contains useful functions for handling Properties * @namespace */ var PropUtils = (function(ns) { /** * get information on this overall script usage * @param {PropertiesStore} store the one to use * @return {object} usage */ ns.getUsage = function (store) { var result = store.getProperty ('usage'); return result ? JSON.parse(result) : null; }; /** * set information on this overall script usage * @param {PropertiesStore} store the one to use * @param {object} value the data to set * @return {object} the data */ ns.setUsage = function (store,data) { store.setProperty ('usage', JSON.stringify(data)); return data; }; /** * update library usage * @param {PropertiesStore} scriptStore the script store * @param {PropertiesStore} userStore the user store * return {object} the two updated usages {script:{},user:{}} */ ns.updateUsage = function (scriptStore, userStore) { var now = new Date().getTime(); // get this users usage, create empty if new var userUsage = ns.getUsage(userStore) || { visits:0, id:Utilities.getUuid(), averageTimeBetweenVisits:0, dateOfLastVisit:0 }; // get this users usage, create empty if new var scriptUsage = ns.getUsage(scriptStore) || { visits:0, averageTimeBetweenVisits:0, uniqueVisitors:0, dateOfLastVisit:0 }; // now update if (scriptUsage.visits) { scriptUsage.averageTimeBetweenVisits = (scriptUsage.averageTimeBetweenVisits * scriptUsage.visits + now - scriptUsage.dateOfLastVisit)/ (scriptUsage.visits+1); } scriptUsage.visits++; scriptUsage.dateOfLastVisit = now; // if its a new user.. if (!userUsage.visits) { scriptUsage.uniqueVisitors ++; } // and the user stuff if (userUsage.visits) { userUsage.averageTimeBetweenVisits = (userUsage.averageTimeBetweenVisits * userUsage.visits + now - userUsage.dateOfLastVisit)/ (userUsage.visits+1); } userUsage.visits++; userUsage.dateOfLastVisit = now; // set the the updated numbers return { script:ns.setUsage(scriptStore,scriptUsage), user:ns.setUsage(userStore, userUsage) }; } // initialize library usage ns.initializeUsage = function () { ns.updateUsage( PropertiesService.getScriptProperties(), PropertiesService.getUserProperties() ); }; return ns; }) ( PropUtils || {});
Opting in for libraries
As I mentioned earlier, I think you that users should have to opt in to your tracking tracking of the usage of your library. But you can make the tracking mandatory, simply by adding this just before the end of your copy of the namespace, which will initiate track every time a script is run that includes your library.
ns.initializeUsage();