Skip to content

Instantly share code, notes, and snippets.

@andrewmacheret
Created July 27, 2017 19:38
Show Gist options
  • Select an option

  • Save andrewmacheret/5973c3a952cad2cebbc3998373d0339c to your computer and use it in GitHub Desktop.

Select an option

Save andrewmacheret/5973c3a952cad2cebbc3998373d0339c to your computer and use it in GitHub Desktop.
ES8
const moment = require('moment-timezone');
const request = require('request-promise-native');
const nhlCssLink = require('./nhl-css-link');
const nhlApiUrl = 'https://statsapi.web.nhl.com/api/v1';
let cacheTeams = null;
const cacheSchedules = {};
async function callNhlApi(path) {
const url = nhlApiUrl + path;
console.log(`calling url: ${url}`);
return await request({uri: url, json: true, timeout: 2000});
}
async function loadTeams() {
if (cacheTeams) return cacheTeams;
return cacheTeams = await callNhlApi('/teams');
}
async function loadSchedule(date, teamId, callback) {
if (!cacheSchedules[date]) cacheSchedules[date] = {};
if (cacheSchedules[date][teamId]) return cacheSchedules[date][teamId];
const url = `/schedule?site=en_nhl&expand=schedule.broadcasts.all&startDate=${date}&endDate=${date}&teamId=${teamId}`;
return cacheSchedules[date][teamId] = await callNhlApi(url);
}
async function myTeamToday(team, date) {
if (!team) {
throw `'team' must be specified`;
}
if (!team.match(/^[a-z\ ]+$/)) {
throw `team must be a lower case set of words, such as 'sharks' or 'maple leafs', was: '${team}'`;
}
if (!date) {
// TODO: determine time zone based on which team was chosen?
date = moment.tz('America/Los_Angeles').format('YYYY-MM-DD');
}
if (!date.match(/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/)) {
throw `date must be in format YYYY-MM-DD, was: '${date}'`;
}
const nhlTeams = await loadTeams();
const nhlTeamNameToId = Object.assign({}, ...nhlTeams.teams.map((nhlTeam) => ({
[ nhlTeam.teamName.toLowerCase() ]: nhlTeam.id
})));
const nhlTeamIdToFullTeamName = Object.assign({}, ...nhlTeams.teams.map((nhlTeam) => ({
[ nhlTeam.id ]: nhlTeam.name
})));
const teamId = nhlTeamNameToId[team];
if (!teamId) {
throw `team not found: '${team}'`;
}
const nhlSchedule = await loadSchedule(date, teamId);
const games = ((nhlSchedule.dates[0] || {}).games || []).map((item) => {
const {
teams: {
home: {
team: {
id: homeId,
name: homeName
}
},
away: {
team: {
id: awayId,
name: awayName
}
}
}
} = item;
const isHome = homeId === teamId;
return {
title: isHome ? `${homeName} vs ${awayName}` : `${awayName} at ${homeName}`,
home: {id: homeId, name: homeName},
away: {id: awayId, name: awayName},
isHome: isHome,
gameDate: item.gameDate,
broadcasts: item.broadcasts ? item.broadcasts.map((broadcast) => broadcast.name) : []
};
});
return {games};
}
exports.api = async (event, context) => {
console.log('called with event:', event);
const apis = {
myTeamToday: () => myTeamToday(event.team, event.date),
cssLink: () => nhlCssLink.loadCssUrl()
};
const apiNotFound = () => { throw `Unsupported or undefined action: ${event.action}` };
try {
const data = await (apis[event.action] || apiNotFound)();
console.log('RESOLVE:', JSON.stringify(data));
return data;
} catch(err) {
console.log('REJECT:', err);
throw typeof(err) === 'string' ? err : err.message || JSON.stringify(err);
}
};
exports.handler = (event, context, callback) => {
exports.api(event, context)
.then((data) => callback(null, data))
.catch((err) => callback(err));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment