The User property service is handy to store user specific properties in, but it can also be used to assign a unique anonymous reference to users and track their visits. Here’s a useful namespace in the cUseful library you can use to do that.
It returns a closure which makes it easy to remove and update items once a registration has happened.

How to use

Here’s the key, and it’s also on github

1EbLSESpiGkI3PYmJqWh3-rmLkYKAtCNPi1L2YCtMgo2Ut8xMThfJ41Ex

Registration

Registering a user looks like this. You need to provide a properties service to user, along with the key to store it under.
var registration = cUseful.UserRegistration.register (PropertiesService.getUserProperties(), 'xliberation_registration_key');
That returns an object that looks like this. It will either be created and entered in the property store or retrieved if this is not the first time this user has been detected. In this example, this is the first time this user has visited. The id will be unique to this user for the lifetime of his properties service entry, and can be used to cross reference other data against if you want.
{"id":"iufcd1xkfio","visits":0,"created":1476786180872,"version":"0.0","lastVisit":1476786180872}
Subsequent visits will return registration objects like this.
{"id":"iufcd1xkfio","visits":2,"created":1476786180872,"version":"0.0","lastVisit":1476786196296}

Updating and removing

The registration object uses closures to avoid  having to provide keys and property store arguments.
It can be updated like this. Updating automatically maintains the visits count and lastVisit date.
registration.update();
It can be removed from the property store like this
registration.remove();

Adding your on data

You can add additional data to the registration object, with something like this.
registration.myData = {
    myAppSetting:100,
    myAppVersion:"1.2"
  };
then when you
registration.update();
your data will be written too, and the result of the next registration will be
{"id":"iufcd1xkfio","visits":4,"created":1476786180872,"version":"0.0","lastVisit":1476786569724,"myData":{"myAppSetting":100,"myAppVersion":"1.2"}}

Exponential backoff

Since the properties store is a rate limited service, exponential backoff is used to ensure successful store access.

cUseful

The cUseful library contains this and many other things posted around this site.
Here’s the key, and it’s also on github

1EbLSESpiGkI3PYmJqWh3-rmLkYKAtCNPi1L2YCtMgo2Ut8xMThfJ41Ex

For more like this, see Google Apps Scripts Snippets

Why not join our forum, follow the blog and or follow me on Twitter for more information and updates.