Last active
March 20, 2019 21:43
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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