Skip to content

Instantly share code, notes, and snippets.

@bitttttten
Last active June 16, 2024 22:21
Show Gist options
  • Select an option

  • Save bitttttten/cb27a73f2909edb5c23ac376fe6b4e02 to your computer and use it in GitHub Desktop.

Select an option

Save bitttttten/cb27a73f2909edb5c23ac376fe6b4e02 to your computer and use it in GitHub Desktop.
Fetch Spotify Recently Played from Netlify function
SPOTIFY_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxx
SPOTIFY_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxx
SPOTIFY_REFRESH_TOKEN=aaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-cccccccccccccccc-dddddddddddddddd-eeeeeeeeeeeeeeee

Prerequisites

You need a couple of things to use the Spotify API: an application and it's client ID and client secret, and an authorisation token. We will generate a refresh token, and use that to generate authorisation tokens on the fly. Once you have these, you can set them as environmental variables or reference them in your dotenv file as in the funtion I read these from process.env.

Spotify client ID, and Spotify client Secret

To generate these two, you need to make a spotify app, then when you visit the page of your application you'll see "Client ID" and "SHOW CLIENT SECRET" which will show you each of these respetively.

Spotify refresh token

Follow the authorisation guide to get your refresh token. When generating your refresh token, make sure you set the correct scopes. For the example here, getting the users recently played tracks, you can see (as the time of writing) it needs the scope user-read-recently-played.

You can also use the web api auth example to generate a refresh token.

/// <reference types="../types.d.ts" />
import { Handler } from "@netlify/functions";
export const handler: Handler = async () => {
try {
const recentlyPlayedContent = await getRecentlyPlayedTracksContent();
return {
statusCode: 200,
body: JSON.stringify(recentlyPlayedContent?.items ?? {}),
};
} catch (err) {
console.error(err);
return {
statusCode: 500,
};
}
};
const getRecentlyPlayedTracksContent: () => Promise<RecentlyPlayedTracksResponse> = async () => {
const Authorization = await getAuthorizationToken();
const response = await fetch(
`https://api.spotify.com/v1/me/player/recently-played`,
{
headers: {
Authorization,
},
}
);
const { status } = response;
// https://developer.spotify.com/documentation/web-api/#response-status-codes
// 204 from spotify means no data was found
if (status === 204) {
return {};
}
// 200 is OK
if (status === 200) {
const data = await response.json();
return data;
}
throw new Error(`Unhandled status: ${status}`);
};
const getAuthorizationToken = async () => {
const SPOTIFY_CLIENT_ID = process.env.SPOTIFY_CLIENT_ID;
const SPOTIFY_REFRESH_TOKEN = process.env.SPOTIFY_REFRESH_TOKEN;
const SPOTIFY_CLIENT_SECRET = process.env.SPOTIFY_CLIENT_SECRET;
const token = btoa(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`);
const Authorization = `Basic ${token}`;
const response = await fetch(`https://accounts.spotify.com/api/token`, {
method: "POST",
headers: {
Authorization,
"Content-Type": "application/x-www-form-urlencoded",
},
body: `grant_type=refresh_token&refresh_token=${SPOTIFY_REFRESH_TOKEN}`,
});
const data = await response.json();
return `Bearer ${data.access_token}`;
};
interface Artist {
href: string;
id: string;
name: string;
type: string;
uri: string;
}
interface Track {
artists: Artist[];
available_markets: string[];
disc_number: number;
duration_ms: number;
explicit: boolean;
href: string;
id: string;
name: string;
preview_url: string;
track_number: number;
type: string;
uri: string;
}
interface RecentlyPlayedTracksItem {
track: Track;
played_at: Date;
}
interface RecentlyPlayedTracksResponse {
items: RecentlyPlayedTracksItem[];
next: string;
cursors: {
after: string;
before: string;
};
limit: number;
href: string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment