Created
January 5, 2019 04:24
-
-
Save ChangedNameTo/cb9de4471532445d29ce84d29ed02710 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 request = require('request-promise@1.0.2'); | |
const SpotifyWebAPI = require('spotify-web-api-node@3.0.0'); | |
/** | |
* NotFoundError | |
*/ | |
class NotFoundError extends Error {} | |
/** | |
* Builds an error response for Slack | |
* @param {String} text | |
* @param {String} color | |
* @param {Boolean} hasMarkDown | |
* @returns {Object} | |
*/ | |
const buildError = (text = 'test', color = 'danger', hasMarkDown = true) => ({ | |
text, | |
color, | |
mrkdwn_in: ['text'], | |
}); | |
/** | |
* Builds a successful response for Slack | |
* @param {String} text | |
* @param {String} thumbnail | |
* @param {String} artist | |
* @param {String} title | |
* @returns {Object} | |
*/ | |
const buildSuccess = (text, thumbnail, artist, title, link) => ({ | |
text, | |
response_type: 'in_channel', | |
attachments: [ | |
{ | |
thumb_url: thumbnail, | |
fields: [ | |
{ | |
title: 'Artist', | |
value: artist, | |
short: true, | |
}, | |
{ | |
title: 'Title', | |
value: title, | |
short: true, | |
}, | |
{ | |
title: 'Stream', | |
value: link ? `<${link}|Listen on Spotify...>` : 'No stream found...', | |
short: false, | |
}, | |
], | |
mrkdwn_in: ['text'], | |
}, | |
], | |
}); | |
/** | |
* Tries to get the currently playing track for a given user, | |
* returns null if none can be found | |
* @param {String} username | |
* @param {String} apiKey | |
* @returns {Promise} { artist, title, thumbnail } | |
*/ | |
const getCurrentTrack = (username, apiKey) => { | |
const url = `http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=${username}&api_key=${apiKey}&format=json&limit=1`; | |
return request.get({ url, method: 'GET', json: true }) | |
.then((response) => { | |
// No response, exit | |
if (!response) { | |
throw new NotFoundError("No response..."); | |
} | |
const track = response.recenttracks.track[0]; | |
console.log(track) | |
var nowPlaying = track["@attr"] ? track["@attr"].nowplaying : false; | |
// No (currently playing) track, exit | |
// if (!track || !track['@attr'] || !track['@attr'].nowplaying) { | |
// throw new NotFoundError("No (currently playing) track..."); | |
// } | |
// Get the large thumbnail from all track images and | |
// return artist, title and said thumbnail | |
const filteredImages = track.image.filter(image => image.size === 'large'); | |
return { | |
text: 'test', | |
artist: track.artist['#text'], | |
title: track.name, | |
thumbnail: filteredImages.length ? filteredImages[0]['#text'] : null, | |
nowPlaying, | |
}; | |
}); | |
}; | |
/** | |
* Tries to find the URL for a given track on Spotify | |
* @param {String} artist | |
* @param {String} title | |
* @param {String} client | |
* @param {String} secret | |
* @returns {Promise} | |
*/ | |
const getSpotifyLink = (artist, title, clientId, clientSecret) => { | |
const spotifyApi = new SpotifyWebAPI({ clientId, clientSecret }); | |
return spotifyApi.clientCredentialsGrant() | |
.then(data => spotifyApi.setAccessToken(data.body.access_token)) | |
.then(() => spotifyApi.searchTracks(`track:${title} artist:${artist}`)) | |
.then((data) => { | |
const track = (data.body.tracks.items || [])[0]; | |
if (!track || !track.external_urls || !track.external_urls.spotify) { | |
throw new NotFoundError('Spotify track could not be found...'); | |
} | |
return track.external_urls.spotify.replace('open.', 'play.'); | |
}); | |
}; | |
module.exports = (ctx, cb) => { | |
const username = ctx.body.text.split(" ")[0]; | |
if (!username.length) { | |
return cb(null, buildError("Please provide a username")); | |
} | |
return getCurrentTrack(username, ctx.secrets.LASTFM_KEY) | |
.then(({ artist, title, thumbnail, nowPlaying }) => { | |
// const text = `*${username}* is currently listening to:`; | |
const text = nowPlaying ? `*${username}* is currently listening to: \n\n` : `*${username}* has last listened to: \n\n`; | |
return getSpotifyLink(artist, title, ctx.secrets.SPOTIFY_CLIENT, ctx.secrets.SPOTIFY_SECRET) | |
.then(link => { | |
const response = buildSuccess(text, thumbnail, artist, title, link); | |
console.log(response); | |
return cb(null, response); | |
}) | |
.catch((error) => { | |
const link = ''; | |
if (error instanceof NotFoundError) { | |
return cb(null, buildSuccess(text, thumbnail, artist, title, link)); | |
} | |
throw error; | |
}); | |
}) | |
.catch((error) => { | |
console.log(error) | |
if (error instanceof NotFoundError) { | |
const text = `I'm sorry, *${username}* isn't playing any tracks currently.`; | |
return cb( null, buildError(text)); | |
} | |
console.error('Something went wrong: ', error); | |
const text = `Something went wrong trying to fetch recent tracks for user *${username}*`; | |
return cb(null, buildError(text)); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment