const { default: axios } = require('axios'); const { response } = require('express'); const express = require('express'); const geohash = require('ngeohash'); var SpotifyWebApi = require('spotify-web-api-node'); const port = process.env.PORT || 8080; const ticketmasterKey = 'qkbDvyaw0KZXm7BZ6hEHAFS6rXVlAlaI'; const categoryMap = { music: 'KZFzniwnSyZfZ7v7nJ', sports: 'KZFzniwnSyZfZ7v7nE', arts_theatre: 'KZFzniwnSyZfZ7v7na', film: 'KZFzniwnSyZfZ7v7nn', miscellaneous: 'KZFzniwnSyZfZ7v7n1' } var spotifyApi = new SpotifyWebApi( { clientId: '25bfc767fb414d5ab4bb496e0b3c2fad', clientSecret: '589108ca59d14670bfcf2acee2d59168', redirectUri: 'https://event-search-ywj.wl.r.appspot.com/' } ); var app = express(); app.use(express.static("./dist/event-search")); app.listen(port, function () { console.log("Backend Application listening on port: " + port); }) app.get('/', function (req, res) { res.send('Event Search Node.js Backend'); }) app.get('/autofill/:keyword', function (req, res) { const autoFillUrl = 'https://app.ticketmaster.com/discovery/v2/suggest'; axios.get(autoFillUrl, { params: { apikey: ticketmasterKey, keyword: req.params.keyword } }).then(response => { var result = []; if (response.data._embedded != null && response.data._embedded.attractions != null) { for (var attraction of response.data._embedded.attractions) { result.push(attraction.name); } } res.json(result); }).catch(error => { console.log(error); }) }) app.get('/events', function (req, res) { console.log(req.query); const eventsUrl = 'https://app.ticketmaster.com/discovery/v2/events.json'; var par = { apikey: ticketmasterKey, keyword: req.query.keyword, radius: req.query.distance, unit: 'miles' } if (req.query.category != 'default') { par.segmentId = categoryMap[req.query.category]; } par.geoPoint = geohash.encode(req.query.lat, req.query.lng, 5); console.log(par); axios.get(eventsUrl, { params: par }).then(response => { var result = []; if (response.data._embedded != undefined) { const events = response.data._embedded.events; for (var event of events) { var processedEvent = {}; processedEvent.name = event.name; processedEvent.id = event.id; processedEvent.iconUrl = ''; if (typeof event.images !== 'undefined') { for (var img of event.images) { if (img.ratio == '4_3') { processedEvent.iconUrl = img.url; break; } } if (processedEvent.iconUrl == '') { processedEvent.iconUrl = event.images[0].url; } } processedEvent.date = ''; processedEvent.time = ''; if (typeof event.dates !== 'undefined' && typeof event.dates.start !== 'undefined') { const eventDate = event.dates.start; if (eventDate.dateTBA) { processedEvent.date = 'TBA'; } else if (eventDate.dateTBD) { processedEvent.date = 'TBD'; } else if (typeof eventDate.localDate !== 'undefined') { processedEvent.date = eventDate.localDate; } if (eventDate.timeTBA) { processedEvent.time = 'TBA'; } else if (eventDate.noSpecificTime) { processedEvent.time = 'No Specific Time' } else if (typeof eventDate.localTime !== 'undefined') { processedEvent.time = eventDate.localTime; } } processedEvent.genre = ''; if (typeof event.classifications !== 'undefined' && event.classifications.length >= 1) { const segmentName = event.classifications[0].segment.name processedEvent.genre = segmentName != 'Undefined' ? segmentName : ''; } processedEvent.venue = ''; if (typeof event._embedded !== 'undefined' && typeof event._embedded.venues !== 'undefined' && event._embedded.venues.length >= 1) { processedEvent.venue = event._embedded.venues[0].name; } result.push(processedEvent); } } res.json(result); }).catch(error => { console.log(error); }) }) app.get('/eventDetail/:id', function (req, res) { const eventDetailurl = 'https://app.ticketmaster.com/discovery/v2/events/' + req.params.id; axios.get(eventDetailurl, { params: { apikey: ticketmasterKey } }).then(response => { var result = {}; result.id = response.data.id; result.name = response.data.name; result.url = ''; if (typeof response.data.url !== 'undefined') { result.url = response.data.url; } result.date = ''; result.time = ''; if (typeof response.data.dates !== 'undefined' && typeof response.data.dates.start !== 'undefined') { const eventDate = response.data.dates.start; if (eventDate.dateTBA) { result.date = 'TBA'; } else if (eventDate.dateTBD) { result.date = 'TBD'; } else if (typeof eventDate.localDate !== 'undefined') { result.date = eventDate.localDate; } if (eventDate.timeTBA) { result.time = 'TBA'; } else if (eventDate.noSpecificTime) { result.time = 'No Specific Time' } else if (typeof eventDate.localTime !== 'undefined') { result.time = eventDate.localTime; } } result.artistTeams = []; result.musicArtists = []; if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.attractions !== 'undefined' && response.data._embedded.attractions.length >= 1) { const attractions = response.data._embedded.attractions; for (var attraction of attractions) { result.artistTeams.push(attraction.name); if (typeof attraction.classifications !== 'undefined' && attraction.classifications.length >= 1 && typeof attraction.classifications[0].segment !== 'undefined' && typeof attraction.classifications[0].segment.name !== 'undefined') { if (attraction.classifications[0].segment.name == 'Music') { result.musicArtists.push(attraction.name); } } } } result.venue = ''; if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.venues !== 'undefined' && response.data._embedded.venues.length >= 1) { result.venue = response.data._embedded.venues[0].name; } result.genres = []; if (typeof response.data.classifications !== 'undefined' && response.data.classifications.length >= 1) { const classification = response.data.classifications[0]; if (typeof classification.segment !== 'undefined' && classification.segment.name != 'Undefined') { result.genres.push(classification.segment.name); } if (typeof classification.genre !== 'undefined' && classification.genre.name != 'Undefined') { result.genres.push(classification.genre.name); } if (typeof classification.subGenre !== 'undefined' && classification.subGenre.name != 'Undefined') { result.genres.push(classification.subGenre.name); } if (typeof classification.type !== 'undefined' && classification.type.name != 'Undefined') { result.genres.push(classification.type.name); } if (typeof classification.subType !== 'undefined' && classification.subType.name != 'Undefined') { result.genres.push(classification.subType.name); } } result.priceRanges = ''; if (typeof response.data.priceRanges !== 'undefined' && response.data.priceRanges.length >= 1) { const price = response.data.priceRanges[0]; if (typeof price.min !== 'undefined') { result.priceRanges += price.min; } if (typeof price.max !== 'undefined') { if (result.priceRanges.length > 0) { result.priceRanges += '-'; } result.priceRanges += price.max; } } result.ticketStatus = ''; if (typeof response.data.dates !== 'undefined' && typeof response.data.dates.status !== 'undefined') { result.ticketStatus = response.data.dates.status.code; } result.seatMapUrl = ''; if (typeof response.data.seatmap !== 'undefined' && typeof response.data.seatmap.staticUrl !== 'undefined') { result.seatMapUrl = response.data.seatmap.staticUrl; } res.json(result); }) }) app.get('/venue/:venue', function (req, res) { const venueUrl = 'https://app.ticketmaster.com/discovery/v2/venues.json'; axios.get(venueUrl, { params: { keyword: req.params.venue.replace('.', ' '), apikey: ticketmasterKey } }).then(response => { var result = {}; if (typeof response.data._embedded !== 'undefined' && typeof response.data._embedded.venues !== 'undefined' && response.data._embedded.venues.length >= 1) { const venue = response.data._embedded.venues[0]; result.name = venue.name; result.address = ''; if (typeof venue.address !== 'undefined' && typeof venue.address.line1 !== 'undefined') { result.address += (venue.address.line1 + ', '); } if (typeof venue.city !== 'undefined' && typeof venue.city.name !== 'undefined') { result.address += (venue.city.name + ', '); } if (typeof venue.state !== 'undefined' && typeof venue.state.name !== 'undefined') { result.address += (venue.state.name); } if (result.address.endsWith(', ')) { result.address = result.address.substring(0, result.address.length - 2); } result.phoneNumber = ''; result.openHours = ''; if (typeof venue.boxOfficeInfo !== 'undefined') { if (typeof venue.boxOfficeInfo.phoneNumberDetail !== 'undefined') { result.phoneNumber = venue.boxOfficeInfo.phoneNumberDetail; } if (typeof venue.boxOfficeInfo.openHoursDetail !== 'undefined') { result.openHours = venue.boxOfficeInfo.openHoursDetail; } } result.generalRule = ''; result.childRule = ''; if (typeof venue.generalInfo !== 'undefined') { if (typeof venue.generalInfo.generalRule !== 'undefined') { result.generalRule = venue.generalInfo.generalRule; } if (typeof venue.generalInfo.childRule !== 'undefined') { result.childRule = venue.generalInfo.childRule; } } } res.json(result); }) }) app.get('/artist/:artist', function (req, res) { const artistName = req.params.artist; spotifyApi.searchArtists(artistName, {limit: 1}) .then( function (data) { console.log('Successfully search artist '+artistName); getArtistDetail(data.body, res); }, function (err) { console.log('Fail to search artist '+artistName, err.body); if (err.body.error.status == '401') { spotifyApi.clientCredentialsGrant().then( function (data) { console.log(data.body); spotifyApi.setAccessToken(data.body.access_token); spotifyApi.searchArtists(artistName, {limit: 1}).then( function(data) { console.log('Successfully search artist '+artistName); getArtistDetail(data.body, res); }, function(err){ console.log('Fail to search artist '+artistName, err.body); res.json({}); } ) }, function(err){ console.log('Something went wrong when retrieving an access token', err.body); res.json({}); } ) } }); }) function getArtistDetail(data, res){ var detail = {}; if(typeof data.artists !== 'undefined' && typeof data.artists.items !== 'undefined' && data.artists.items.length >= 1){ const artist = data.artists.items[0]; detail.name = artist.name; detail.popularity = -1; if(typeof artist.popularity !== 'undefined'){ detail.popularity = artist.popularity; } detail.followers = -1; if(typeof artist.followers !== 'undefined' && typeof artist.followers.total !== 'undefined'){ detail.followers = artist.followers.total; } detail.link = ''; if(typeof artist.external_urls !== 'undefined' && typeof artist.external_urls.spotify !== 'undefined'){ detail.link = artist.external_urls.spotify; } detail.artistImgUrl = ''; if(typeof artist.images !== 'undefined' && artist.images.length >= 1){ detail.artistImgUrl = artist.images[0].url; } detail.albumsImgsUrls = []; spotifyApi.getArtistAlbums(artist.id, {limit: 3}).then( function(data){ console.log('Successfully get albums of ' + artist.name); detail.albumsImgsUrls = getAlbums(data.body) res.json(detail); }, function(err){ console.log('Fail to get albums of ' + artist.name, err); if(err.body.error.status == '401'){ spotifyApi.clientCredentialsGrant().then( function (data) { console.log(data.body); spotifyApi.setAccessToken(data.body.access_token); spotifyApi.getArtistAlbums(artist.id, {limit: 3}).then( function(data) { console.log('Successfully get albums of ' + artist.name); detail.albumsImgsUrls = getAlbums(data.body) res.json(detail); }, function(err){ console.log('Fail to get albums of ' + artist.name, err.body); res.json(detail); } ) }, function(err){ console.log('Something went wrong when retrieving an access token', err.body); res.json(detail); } ) } } ) } } function getAlbums(data){ var albums = []; if(typeof data.items !== 'undefined' && data.items.length >= 1){ for(var album of data.items){ if(typeof album.images !== 'undefined' && album.images.length >= 1){ albums.push(album.images[0].url); } } } return albums; }