Integrating Spotify into Laravel involves leveraging the Spotify Web API to access and manage Spotify's vast music database.
Step 1 : Get Credentials.
To obtain credentials, visit https://developer.spotify.com/, sign in or create an account, and register a new app. Enter the necessary details, and once completed, your app will be created successfully.
After creating the app, navigate to the app's details and select the settings option. In the settings, you will find the 'Client ID' and 'Client Secret'. Ensure that you keep these keys secure and avoid exposing them in publicly accessible locations.
Step 2 : Create Access Token Function.
Next, open your Laravel project and create a controller named 'SpotifyController'. To generate the controller, execute the command shown below.
php artisan make:controller SpotifyController
Let's move to the 'SpotifyController' and begin working on the 'getAccessToken' function.
- This function retrieves an access token from Spotify's API using the client credentials flow.
- It checks if the current token has expired and, if so, fetches a new one.
- The retrieved access token and its expiration time are stored in the session for future use.
- Tokens are securely encoded, and the function avoids unnecessary API calls by caching the token until it expires.
use GuzzleHttp\Client;
public function getAccessToken()
{
// Retrieve the session expiration time from the session storage.
$expiryTime = session()->get('session_expiry');
// Check if the expiration time is empty or has already passed.
if (empty($expiryTime) || $expiryTime->isPast())
{
// Spotify API Client ID and Client Secret (should ideally be stored securely in environment variables).
$client_id = 'YOUR_CLIENT_ID';
$client_secret = 'YOUR_SECRET_KEY';
// Encode the Client ID and Client Secret in Base64 as required for Spotify's API authorization.
$token = base64_encode($client_id . ':' . $client_secret);
// Create a new HTTP client instance.
$client = new Client();
// Make a POST request to Spotify's token API to obtain an access token.
$response = $client->request('POST', 'https://accounts.spotify.com/api/token', [
'form_params' => [
'grant_type' => 'client_credentials', // Set the grant type to "client_credentials".
],
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded', // Specify content type.
'Authorization' => 'Basic ' . $token, // Provide authorization using the Base64 encoded token.
],
]);
// Check if the response status code is 200 (success).
if ($response->getStatusCode() === 200)
{
// Decode the response body to extract the access token.
$data = json_decode($response->getBody(), true);
$accessToken = $data['access_token'];
// Calculate the token's expiry time (set to 59 minutes from now).
$expiry = (new \Carbon\Carbon())->addMinutes(59);
// Store the expiry time in the session.
session()->put('session_expiry', $expiry);
// Store the access token in the session.
session()->put('access_token', $accessToken);
// Return the retrieved access token.
return $accessToken;
}
else
{
// If the API request fails, return an empty string.
return '';
}
}
else
{
// If the token is still valid, retrieve it from the session and return it.
return session()->get('access_token');
}
}
Step 2 : Fetch Track using Spotify API
- This function retrieves track details from Spotify using the track ID and the 'getAccessToken' method for authentication.
- The Spotify API endpoint is constructed dynamically, optionally including the market parameter.
- The response is parsed, and key details (e.g., track metadata, album, artist names, popularity, and album images) are extracted and returned.
- Errors are handled gracefully by returning the status code if the request fails.
public function getTrack($spotify_track_id)
{
// Retrieve the access token using a separate function (getAccessToken).
$accessToken = $this->getAccessToken();
// Create an instance of the HTTP client for making API requests.
$client = new Client();
// Define the market where the track data will be fetched (e.g., 'US').
$market = 'US';
// If the market variable is set, include it as a query parameter in the API endpoint.
if (!empty($market))
{
$endpointUrl = 'https://api.spotify.com/v1/tracks/' . $spotify_track_id . '?market=' . $market;
}
else
{
// If the market is empty, exclude it from the API endpoint URL.
$endpointUrl = 'https://api.spotify.com/v1/tracks/' . $spotify_track_id;
}
// Define the request parameters: headers and query data.
$params = [
'query' => [], // No additional query parameters in this case.
'headers' => [
'Authorization' => 'Bearer ' . $accessToken, // Add the access token for authentication.
],
];
// Send a GET request to the Spotify API with the specified endpoint and parameters.
$response = $client->request('GET', $endpointUrl, $params);
// Check if the API response status code is 200 (success).
if ($response->getStatusCode() === 200)
{
// Parse the JSON response body into an associative array.
$data = json_decode($response->getBody(), true);
// Extract album-related details from the track data.
$trackDetails = $data['album'];
// Extract specific image details (e.g., medium-sized image).
$imageDetails = $trackDetails['images'][1];
// Initialize variables to store artist information.
$artistName = '';
$artistId = '';
// Loop through the list of artists associated with the track.
foreach ($data['artists'] as $key => $artist)
{
// Append each artist's name to the artistName variable, separated by a comma if there are multiple artists.
if ($key > 0)
{
$artistName .= ' ,' . $artist['name'];
}
else
{
$artistName = $artist['name'];
}
}
// Prepare the final array of track data to return.
$rtnData = [
'id' => $trackDetails['id'], // Track ID
'name' => $trackDetails['name'], // Track name
'release_date' => $trackDetails['release_date'], // Release date of the track/album
'href' => $data['href'], // API URL for the track
'duration_ms' => $data['duration_ms'], // Track duration in milliseconds
'popularity' => $data['popularity'], // Track popularity score
'artist_name' => $artistName, // Names of all artists
'artist_id' => $artistId, // Artist ID (currently unused but placeholder exists)
'image_details' => $imageDetails, // Image details (e.g., album cover)
];
// Return the prepared track data.
return $rtnData;
}
else
{
// If the response status code is not 200, return an error message with the status code.
return 'Error : ' . $response->getStatusCode();
}
}
Step 3 : Display Fetched Track
Next, define a function called 'index' within the 'SpotifyController' and return its result to a view file.
public function index()
{
$spotify_track_id = '6KYOlIwDHbrbeBbJEtQ0Fj';
$track = $this->getTrack($spotify_track_id);
return view('spotify.index',compact('track'));
}
I have manually added the Spotify track ID for simplicity. However, it is assumed that you might be implementing a proper flow to retrieve tracks from artists, albums, or a user's list. To keep things straightforward, I am using a manually provided track ID.
For more details on Spotify IDs and URIs, refer to Spotify's official documentation : https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids
Now let's create blade file to display fetched data, So create a file in 'resources/views/spotify/index.blade.php'
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12 text-center pb-4">
<img src="{{ $track['image_details']['url'] }}" alt="Thumbnail" height="{{ $track['image_details']['height'] }}px" width="{{ $track['image_details']['width'] }}px">
</div>
<div class="col-md-4 text-center">
<div class="card">
<div class="card-body">
<p><b>Name : </b> {{ $track['name'] }}</p>
<p><b>Release Date : </b> {{ \Carbon\Carbon::parse($track['release_date'])->format('d M, Y') }}</p>
<p><b>Popularity : </b> {{ $track['popularity'] }}</p>
<p><b>Artist Name : </b> {{ $track['artist_name'] }}</p>
<p class="text-center"><a href="https://open.spotify.com/track/{{ $track['id'] }}" target="_blank">Listen on Spotify</a></p>
<p class="text-center mb-0"><a href="https://open.spotify.com/artist/{{ $track['artist_id'] }}" target="_blank">More from {{ $track['artist_name'] }}</a></p>
</div>
</div>
</div>
</div>
</div>
@endsection
Note : This process does not allow Spotify content to be played directly on your site. It involves a more complex and separate procedure, which we will cover in the future.