17 February 2017

Monitoring new users with Pushover

fabric

I recently release a side project I worked on with a friend of mine. As I’m sure you know, when you release something into the world it’s really hard to go by your day without checking the analytics!

As the stats freaks that we are, we decided to use Fabric for the app. We chose Fabric as they have a great mobile app with a widget (great for quickly monitoring active users when you’re out and about) and they have an incredible live web dashboard too:

fabric

However, during the day we’ve found ourselves only looking at one stat, new users. As all the stats are live, I thought it might be a fun challenge to try and use my skills to figure out if it would be possible to send myself an alert when we get a new user. This might be annoying if you’re app is super popular, although the script sends at most one notification per 5 minutes

I time-boxed two hours after work to try figure something out, to give myself a deadline to ensure that I actually produce something.

Me being me, when I sit down to write a script I turn to Node.js. I find nothing easier/faster than to write a quick hacky js file and being able to make use of all the great modules via npm/yarn.

As I gave myself a couple of hours, I didn’t want to create an iOS app to receive the notifications and had recently come across a service called Pushover. Pushover allows you to quickly send notifications to your devices (and groups of devices - perfect for me and my friend) via a REST API.

Here’s the script:

var Pushover = require('node-pushover');
var moment = require('moment');
var request = require('request');
// Fill out with your secrets
var secrets = {
pushover: {
token: '',
user: ''
},
fabric: {
organizationId: '',
applicationId: '',
cookie: '',
crashlyticsDeveloperToken: ''
}
}
if (!Array.prototype.last){
Array.prototype.last = function(){
return this[this.length - 1];
};
};
var push = new Pushover({
token: secrets.pushover.token,
user: secrets.pushover.user
});
function requestOptions(fromDate, toDate) {
return {
url: 'https://fabric.io/api/v2/organizations/' + secrets.fabric.organizationId + '/apps/' + secrets.fabric.applicationId + '/growth_analytics/daily_new.json?start=' + fromDate + '&end=' + toDate + '&transformation=seasonal',
method: 'GET',
headers: {
'Cookie': secrets.fabric.cookie,
'X-CRASHLYTICS-DEVELOPER-TOKEN': secrets.fabric.crashlyticsDeveloperToken
}
}
}
function sendNotification(newUserCount) {
push.send("New Road Code User!", "There are now " + newUserCount + " new users today.", function (err, res){
if (err) {
console.log("We have an error:");
console.log(err);
console.log(err.stack);
} else {
console.log("Message send successfully");
console.log(res);
}
});
}
// Save a variable to the last known user count
var lastNewUserCount = 1
function updateLastUserCount() {
// Fetch the UTC date of today + 1
let date = moment().utc().startOf('date');
let toDate = Math.floor(date / 1000)
let fromDate = toDate - 60 * 60 * 24 * 5 // Last 5 days..
let options = requestOptions(fromDate, toDate)
console.info("Checking user count at " + moment().format('MMMM Do YYYY, h:mm:ss a'))
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
try {
var json = JSON.parse(body)
var lastEntry = json.series.last().last()
console.info("New user count: " + lastEntry);
// Update lastUserCount & send notification if the count is different
// It can be different when it ticks over to a new day.
if (lastNewUserCount != lastEntry) {
sendNotification(lastEntry)
lastNewUserCount = lastEntry
} else {
console.info("User count not changed")
}
} catch (e) {
console.error("Failed to parse json response")
console.error(e)
}
} else {
console.error("Invalid response status code")
}
})
}
setInterval(function () {
updateLastUserCount()
}, 1000 * 60 * 5);
// Perform the initial update
updateLastUserCount()
view raw index.js hosted with ❤ by GitHub
{
"name": "pushover-monitor",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"moment": "^2.17.1",
"node-pushover": "^0.2.2",
"request": "^2.79.0"
}
}
view raw package.json hosted with ❤ by GitHub

The premise is simple, run it on a computer that is always on and every 5 minutes the script will poll the Fabric API for the new users stats, and if it’s different to the last known value, send a Pushover notification to alert us that we’ve a new user!

If this gets annoying, it can only be a good thing 😎

Will Townsend

Hey 👋 I'm Will Townsend, I hope you enjoyed this post. If you have any questions you can contact me on Mastodon and maybe Twitter, cheers!