Skip to content

Instantly share code, notes, and snippets.

@david-crespo
Last active March 20, 2019 21:43
Show Gist options
  • Save david-crespo/3b6a1ff130afec387588c239145280d5 to your computer and use it in GitHub Desktop.
Save david-crespo/3b6a1ff130afec387588c239145280d5 to your computer and use it in GitHub Desktop.
Fetch latest polls from 538 and ping IFTTT if there are any
#! /app/.heroku/node/bin/node
"use strict";
const moment = require('moment-timezone');
const request = require('request');
const _ = require('lodash');
const updatesURL = 'http://projects.fivethirtyeight.com/2016-election-forecast/updates.json';
const forecastURL = 'http://projects.fivethirtyeight.com/2016-election-forecast/US.json';
const notificationURL = 'https://maker.ifttt.com/trigger/new_polls/with/key/<YOUR_KEY_HERE>';
const intervalMinutes = 10;
const now = moment();
function isNew (poll) {
const added = moment.tz(poll.added * 1000, 'America/New_York');
return now.diff(added, 'minutes') < intervalMinutes;
}
function sendNotification (msg) {
request({
url: notificationURL,
method: 'POST',
json: true,
body: {
value1: msg
}
}, function (err, res, body) {
if (err) {
console.log('Error posting to IFTTT:', err);
} else {
console.log(`Successfully posted to IFTTT: "${msg}"`);
}
});
}
request({url: updatesURL, gzip: true}, function (err, res, body) {
if (err || res.statusCode !== 200) {
console.log('Error fetching polls:', err || res.statusCode);
return;
}
const polls = JSON.parse(body);
console.log(`Fetched ${polls.length} polls`);
const newPolls = _.takeWhile(polls, isNew);
// const newPolls = polls.slice(0, 5);
if (newPolls.length === 0) {
console.log('No new polls')
return;
}
let statesBreakdown;
if (newPolls.length === 1) {
statesBreakdown = newPolls[0].state;
} else {
statesBreakdown = _
.chain(newPolls)
.groupBy('state')
.map((ps, state) => `${ps.length} ${state}`)
.join(', ')
.value();
}
request({url: forecastURL, gzip: true}, function (err, res, body) {
if (err || res.statusCode !== 200) {
console.log('Error fetching forecast:', err || res.statusCode);
return;
}
console.log('Fetched forecast');
const latest = JSON.parse(body).forecasts.latest;
const clinton = _.round(latest.D.models.polls.winprob, 1).toString();
const trump = _.round(latest.R.models.polls.winprob, 1).toString();
const s = newPolls.length === 1 ? '' : 's';
const msg = `${newPolls.length} new poll${s}: ${statesBreakdown}\nClinton ${clinton}%, Trump ${trump}%`;
sendNotification(msg);
});
});
{
"name": "538-poll-updates",
"version": "0.0.1",
"description": "Fetch latest polls from 538 and send a push notification through IFTTT.",
"main": "fetchPolls.js",
"scripts": {
"start": "echo \"Nothing to run!\" && exit"
},
"author": "David Crespo",
"license": "MIT",
"dependencies": {
"lodash": "^4.16.1",
"moment-timezone": "^0.5.5",
"request": "^2.75.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment