Skip to content

Instantly share code, notes, and snippets.

@m1guelpf
Created May 26, 2023 04:18
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save m1guelpf/5249564b5fd41a1b52fb76be655f664e to your computer and use it in GitHub Desktop.
Save m1guelpf/5249564b5fd41a1b52fb76be655f664e to your computer and use it in GitHub Desktop.
Next.js App Route for getting the current playing song on Spotify (or a cached version)
import redis from '@/lib/redis'
import { tap } from '@/lib/utils'
import { NextResponse } from 'next/server'
import { NowPlaying } from '@/types/activities'
import { base64_encode, use } from '@/lib/utils'
type SpotifyResponse = {
is_playing: boolean
progress_ms: number
item: {
name: string
external_urls: {
spotify: string
}
duration_ms: number
artists: {
name: string
}[]
album: {
images: {
url: string
}[]
}
}
}
export const revalidate = 60 // seconds
export async function GET(): Promise<NextResponse> {
const token = await redis.get('spotify:token')
if (!token) return NextResponse.json({ error: "Couldn't connect to Spotify." }, { status: 401 })
const response = await fetch('https://api.spotify.com/v1/me/player/currently-playing', {
headers: { Authorization: `Bearer ${token}` },
})
if (response.status == 401) {
await refreshToken()
return GET()
}
if (response.status == 204) {
const cachedPlaying = (await redis.hgetall<NowPlaying>('spotify:now-playing')) ?? {}
return NextResponse.json({ ...cachedPlaying, live: false } satisfies NowPlaying)
}
const nowPlaying = tap(
use<SpotifyResponse, NowPlaying>(await response.json(), data => ({
title: data.item.name,
live: data.is_playing,
url: data.item.external_urls.spotify,
cover_img: data.item.album.images[0].url,
artist: data.item.artists.map(artist => artist.name).join(', '),
})),
data => redis.hset('spotify:now-playing', data)
)
return NextResponse.json(nowPlaying satisfies NowPlaying)
}
const refreshToken = async () => {
const refreshToken = await redis.get('spotify:refresh')
const { access_token } = await fetch(
`https://accounts.spotify.com/api/token?grant_type=refresh_token&refresh_token=${refreshToken}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${base64_encode(`${process.env.SPOTIFY_ID}:${process.env.SPOTIFY_SECRET}`)}`,
},
}
).then(res => res.json())
await redis.set('spotify:token', access_token)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment