DEV Community

Tariq Mehmood
Tariq Mehmood

Posted on

Create a Smart Spotify Bot with Node.js & Web API

If you’re like me, your playlists are your digital mixtapes – carefully curated soundtracks for workouts, chill sessions, work grinds, or late-night drives. But building and maintaining them manually? That can be a drag.

That’s when I had this idea:

What if I could write a bot that builds playlists based on my listening habits, audio features, and moods – automatically?

With the power of the Spotify Web API, a little bit of Node.js, and some creative logic, I built a small utility bot that does just that. In this post, I’ll walk you through how you can build your own Spotify Playlist Curator Bot that creates smart playlists based on your taste.

What You’ll Need

Before we dive into code, let’s list the requirements:

  • A Spotify Developer Account
  • A Spotify App with its Client ID and Client Secret
  • A Node.js project setup
  • Some basic familiarity with JavaScript, OAuth2, and REST APIs
  • A text editor (I used VS Code)
  • And of course, your music taste

Step 1: Authenticate with Spotify (OAuth 2.0 Authorization Code Flow)

Spotify requires OAuth2 to access user data, so the first thing we need is to authenticate the user and obtain an access token.

Here’s a quick setup using the express framework and axios to handle HTTP requests:

1. Setup your environment:

npm init -y
npm install express axios dotenv querystring open
Enter fullscreen mode Exit fullscreen mode

Create a .env file:

SPOTIFY_CLIENT_ID=your_client_id_here
SPOTIFY_CLIENT_SECRET=your_client_secret_here
SPOTIFY_REDIRECT_URI=http://localhost:8888/callback
Enter fullscreen mode Exit fullscreen mode

2. Create a basic Express server

// server.js
require('dotenv').config();
const express = require('express');
const axios = require('axios');
const querystring = require('querystring');
const open = require('open');

const app = express();
const port = 8888;

const SCOPES = [
  'user-read-private',
  'user-read-email',
  'playlist-modify-public',
  'playlist-modify-private',
  'user-top-read',
].join(' ');

app.get('/login', (req, res) => {
  const queryParams = querystring.stringify({
    response_type: 'code',
    client_id: process.env.SPOTIFY_CLIENT_ID,
    scope: SCOPES,
    redirect_uri: process.env.SPOTIFY_REDIRECT_URI,
  });

  res.redirect(`https://accounts.spotify.com/authorize?${queryParams}`);
});

app.get('/callback', async (req, res) => {
  const code = req.query.code;

  try {
    const response = await axios.post(
      'https://accounts.spotify.com/api/token',
      querystring.stringify({
        grant_type: 'authorization_code',
        code,
        redirect_uri: process.env.SPOTIFY_REDIRECT_URI,
      }),
      {
        headers: {
          Authorization:
            'Basic ' +
            Buffer.from(
              `${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`
            ).toString('base64'),
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      }
    );

    const { access_token, refresh_token } = response.data;

    res.send('✅ Authenticated. Now you can close this tab and run your bot.');
    console.log('Access Token:', access_token);
    console.log('Refresh Token:', refresh_token);

    // Store these tokens securely or pass to your bot logic
  } catch (err) {
    console.error('Error fetching access token:', err.response.data);
    res.send('Authentication failed.');
  }
});

app.listen(port, () => {
  console.log(`> Visit http://localhost:${port}/login to authenticate`);
  open(`http://localhost:${port}/login`);
});
Enter fullscreen mode Exit fullscreen mode

Run this with:

node server.js
Enter fullscreen mode Exit fullscreen mode

Once authenticated, you'll get your tokens in the console.

Step 2: Get User's Top Tracks

Spotify allows access to the user's most played tracks over different time ranges. Let's use that to seed our playlist.

async function getTopTracks(token, time_range = 'short_term') {
  const response = await axios.get(
    `https://api.spotify.com/v1/me/top/tracks?limit=20&time_range=${time_range}`,
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  return response.data.items;
}
Enter fullscreen mode Exit fullscreen mode

You can choose time ranges like:

  • short_term (last 4 weeks)
  • medium_term (last 6 months)
  • long_term (all time)

Step 3: Analyze Tracks & Create Playlist

Spotify Premium APK offers audio features for every track — things like danceability, energy, tempo, and valence (positivity).

async function getAudioFeatures(token, trackIds) {
  const ids = trackIds.join(',');
  const response = await axios.get(
    `https://api.spotify.com/v1/audio-features?ids=${ids}`,
    {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    }
  );

  return response.data.audio_features;
}
Enter fullscreen mode Exit fullscreen mode

Based on this, let’s filter tracks with:

  • danceability > 0.7
  • energy > 0.6
  • valence > 0.5

You can adjust this for your mood.

Now Create the Playlist:

async function createPlaylist(token, userId, name, description) {
  const response = await axios.post(
    `https://api.spotify.com/v1/users/${userId}/playlists`,
    {
      name,
      description,
      public: false,
    },
    {
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
    }
  );

  return response.data.id;
}
Enter fullscreen mode Exit fullscreen mode

And finally, add songs:

async function addTracksToPlaylist(token, playlistId, uris) {
  await axios.post(
    `https://api.spotify.com/v1/playlists/${playlistId}/tracks`,
    {
      uris,
    },
    {
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
    }
  );
}
Enter fullscreen mode Exit fullscreen mode

Putting It All Together

Here’s the logic of the final bot:

async function runBot(accessToken) {
  const topTracks = await getTopTracks(accessToken, 'short_term');
  const trackIds = topTracks.map(track => track.id);

  const features = await getAudioFeatures(accessToken, trackIds);

  const filteredTracks = topTracks.filter((track, i) => {
    const f = features[i];
    return f && f.danceability > 0.7 && f.energy > 0.6 && f.valence > 0.5;
  });

  const uris = filteredTracks.map(track => track.uri);

  const me = await axios.get('https://api.spotify.com/v1/me', {
    headers: { Authorization: `Bearer ${accessToken}` },
  });

  const userId = me.data.id;

  const playlistId = await createPlaylist(
    accessToken,
    userId,
    '💃 Curated Mood Booster',
    'Auto-curated feel-good tracks based on your recent listening habits.'
  );

  await addTracksToPlaylist(accessToken, playlistId, uris);

  console.log(`✅ Playlist created with ${uris.length} tracks!`);
}
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

This project was a blast.

What I love about this is how easy it is to build something meaningful with tools like Node.js and the Spotify Web API. With a few API calls and some logic, you’ve got a personal DJ assistant that creates vibe-based playlists for you.

You can take this further:

  • Schedule the bot to run weekly with a cron job
  • Email yourself a summary of your top tracks
  • Analyze genres or artists
  • Build mood-based playlists for different times of day

🧪 Bonus: Ideas to Expand

  • Add a web dashboard using React or Vue
  • Store history of generated playlists
  • Use AI/ML to predict mood from listening patterns
  • Integrate with Discord to share playlists

Top comments (0)