Created
December 8, 2021 02:19
-
-
Save rystaf/31fb3b699b6c0a696311a7309986fb33 to your computer and use it in GitHub Desktop.
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
const fs = require('fs') | |
const https = require('https') | |
const querystring = require('querystring') | |
const ord = (i) => { | |
const j = i % 10, | |
k = i % 100; | |
if (j == 1 && k != 11) return i + "st"; | |
if (j == 2 && k != 12) return i + "nd"; | |
if (j == 3 && k != 13) return i + "rd"; | |
return i + "th"; | |
} | |
const request = (options, postData) => new Promise((resolve, reject) => { | |
if (postData) { | |
var payload = querystring.stringify(postData) | |
options.headers = { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
'Content-Length': payload.length, | |
...options.headers | |
} | |
} | |
const req = https.request(options, (response) => { | |
let data = '' | |
response.on('data', chunk => { | |
data = data + chunk.toString(); | |
}) | |
response.on('end', () => resolve(data)) | |
}) | |
req.on('error', (error) => reject(error)) | |
if (postData) req.write(payload) | |
req.end(); | |
}) | |
const main = async () => { | |
const config = require('./config.json') | |
const now = new Date() | |
console.log(now, 'fetching leaderboard') | |
const lb = JSON.parse(await request({ | |
hostname: 'adventofcode.com', | |
port: 443, | |
path: `/${now.getFullYear()}/leaderboard/private/view/${config.leaderboardID}.json`, | |
method: 'GET', | |
headers: { | |
'Cookie': `session=${config.session}` | |
} | |
})) | |
const members = Object.keys(lb.members).map(id => { | |
const {name, completion_day_level: days, local_score, stars} = lb.members[id] | |
const solves = Array.apply(null, Array(now.getDate())).map((x,i)=> i+1).map(d => { | |
const parts = Object.keys(days[d]||{}).map(x => parseInt(x)) | |
return ['1','2'].map(p => { | |
const t = (days[d]||{})[p]?.get_star_ts | |
return t ? new Date(1000 * t) : t | |
}) | |
}) | |
return {name, solves, local_score, stars} | |
}).sort((a,b)=> b.local_score-a.local_score) | |
if (!fs.existsSync('./cache.json')) { | |
return fs.writeFileSync(`./cache.json`, JSON.stringify(members, null, 2)) | |
} | |
const cache = require('./cache.json') | |
const updates = members.flatMap((m, mi) => { | |
const rank = mi + 1 | |
const mcache = cache.find(x => x.name == m.name) | |
const oldrank = cache.findIndex(x => x.name == m.name) + 1 | |
if (!mcache) { | |
return `*${m.name}* has joined the leaderboard with ${m.stars} star${m.stars != 1 ? 's':''}, which puts them in ${ord(rank)} place.` | |
} | |
const newSolves = m.solves | |
.map((s,d) => ({ | |
name: m.name, | |
day: d + 1, | |
timestamps: s, | |
rank: s.map((x,p) => { | |
return [...members].sort((a,b) => a.solves[d][p] - b.solves[d][p]).findIndex(mm => mm.name == m.name) | |
}) | |
})) | |
.filter((s, d) => { | |
return mcache.solves[d].filter(x => x).length != s.timestamps.filter(x => x).length | |
}) | |
.map(s => { | |
const place = rank == oldrank | |
? `They are still in *${ord(rank)}* place.` | |
: `They moved from ${ord(oldrank)} place to *${ord(rank)}* place.` | |
let puzzle = s.day | |
let part = 1 | |
if (!s.timestamps[1]) { | |
puzzle += ' part 1' | |
part = 0 | |
} | |
return `*${m.name}* finished day ${puzzle}! They were the *${ord(s.rank[part]+1)}* person to do so. ${place}` | |
}) | |
return newSolves | |
}).filter(x => x) | |
console.log(updates.join('\n')) | |
const response = request({ | |
hostname: 'hooks.slack.com', | |
port: 443, | |
path: config.webhookPath, | |
method: 'POST', | |
}, {"payload": `{\"channel\": \"${config.channel}\", \"text\": \"${updates.map((x,i,s) => (s.length > 1 ? "• ":"")+x).join('\n')}\"}`}) | |
fs.writeFileSync(`./cache.json`, JSON.stringify(members, null, 2)) | |
} | |
main() | |
setInterval(main, 1000 * 60 * 15) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment