Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ChangedNameTo/cb9de4471532445d29ce84d29ed02710 to your computer and use it in GitHub Desktop.
Save ChangedNameTo/cb9de4471532445d29ce84d29ed02710 to your computer and use it in GitHub Desktop.
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