Skip to main content

Prerequisites

  • Node.js installed on your machine
  • A Spotify Developer account
  • A Notion account

Step 1 - Get Your API Keys

Spotify API Key
1
Log in to your Spotify Developer account.
3
Click on Create an App.
4
Fill in the required details and click Create.
5
Copy the Client ID and Client Secret.
Notion API Key
1
Log in to your Notion account.
3
Click on New Integration.
4
Fill in the required details and click Submit.
5
Copy the generated Internal Integration Token.

Step 2 - Set Up Your Notion Database

1
Create a new database in Notion with the following properties:
  • Title (Title)
  • Artist (Text)
  • Album (Text)
  • Duration (Number)
  • Popularity (Number)
  • External_URL (URL)
  • Key (Text)
  • Mode (Text)
  • Tempo (Number)
  • Danceability (Number)
2
Share the database with your integration:
  • Click on the three dots in the top-right corner of the page.
  • Under Connections, click on Connect to and search for your integration and connect to it.

Step 3 - Project Structure

This step is not necessary but we suggest projects to be structured like so:
project-root/
├── src/
   ├── config/
   └── spotify.js
   └── notion.js
   ├── integrations/
   ├── spotifyIntegration.js
   └── notionIntegration.js
   ├── main.js
├── .env
├── package.json

Step 4 - Create .env file

Create a .env file and populate with the following information:
YAML
NOTION_TOKEN='your_notion_integration_token'
SPOTIFY_CLIENT_ID='your_spotify_client_id'
SPOTIFY_CLIENT_SECRET='your_spotify_client_secret'
SPOTIFY_PLAYLIST_ID='your_playlist_id'
NOTION_DATABASE_ID='your_notion_database_id'

Step 5 - Packages

Install the required Node.js packages using the following command:
Shell
npm install @notionhq/client dotenv
Create a package.json file and add the following:
JSON
{
    "name": "spotify_integration",
    "version": "1.0.0",
    "main": "src/main.js",
    "scripts": {
        "start": "node src/main.js"
    },
    "dependencies": {
        "@notionhq/client": "^1.0.4",
        "dotenv": "^8.6.0",
    }
}

Step 6 - Set Up Spotify and Notion API Client

Create a spotify.js file to set up the Spotify API client.
JavaScript
const querystring = require('querystring');

// Function to get Spotify access token
async function getSpotifyAccessToken() {
  const fetch = (await import('node-fetch')).default;
  const postData = querystring.stringify({
    grant_type: 'client_credentials'
  });

  const response = await fetch('https://accounts.spotify.com/api/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': `Basic ${Buffer.from(`${process.env.SPOTIFY_CLIENT_ID}:${process.env.SPOTIFY_CLIENT_SECRET}`).toString('base64')}`
    },
    body: postData
  });

  const data = await response.json();
  return data.access_token;
}

module.exports = { getSpotifyAccessToken };
Create a notion.js file to set up the Notion API client.
JavaScript
// notion.js
const { Client } = require('@notionhq/client');
const dotenv = require('dotenv');

dotenv.config();

const notion = new Client({ auth: process.env.NOTION_TOKEN });
const databaseId = process.env.NOTION_DATABASE_ID;

module.exports = { notion, databaseId };

Step 7 - Set Up Integrations

Create spotifyIntegration.js to fetch tracks from a Spotify playlist.
JavaScript
const { getSpotifyAccessToken } = require('../config/spotify');

// Helper function to make GET requests
async function fetchJson(url, headers) {
  const fetch = (await import('node-fetch')).default;
  const response = await fetch(url, { headers });
  return response.json();
}

// Fetch tracks from a Spotify playlist
async function getSpotifyPlaylistTracks(playlistId) {
  const accessToken = await getSpotifyAccessToken();
  const headers = {
    'Authorization': `Bearer ${accessToken}`
  };

  const playlistResponse = await fetchJson(`https://api.spotify.com/v1/playlists/${playlistId}/tracks`, headers);
  const tracks = playlistResponse.items.map(item => {
    const track = item.track;
    return {
      title: track.name,
      artist: track.artists.map(artist => artist.name).join(', '),
      album: track.album.name,
      duration: track.duration_ms,
      popularity: track.popularity,
      external_url: track.external_urls.spotify,
      id: track.id
    };
  });

  // Fetch additional audio features for each track
  const trackIds = tracks.map(track => track.id).join(',');
  const audioFeaturesResponse = await fetchJson(`https://api.spotify.com/v1/audio-features?ids=${trackIds}`, headers);
  const audioFeatures = audioFeaturesResponse.audio_features;

  return tracks.map((track, index) => ({
    ...track,
    key: audioFeatures[index].key,
    mode: audioFeatures[index].mode,
    tempo: audioFeatures[index].tempo,
    danceability: audioFeatures[index].danceability
  }));
}

module.exports = { getSpotifyPlaylistTracks };
Additionally create notionIntegration.js to populate the database with the track information.
JavaScript
const { Client } = require('@notionhq/client');

// Initialize the Notion client
const notion = new Client({ auth: process.env.NOTION_TOKEN });

// Add data to the Notion database
async function addToNotionDatabase(databaseId, track) {
  try {
    await notion.pages.create({
      parent: { database_id: databaseId },
      properties: {
        'Title': {
          title: [
            {
              text: {
                content: track.title
              }
            }
          ]
        },
        'Artist': {
          rich_text: [
            {
              text: {
                content: track.artist
              }
            }
          ]
        },
        'Album': {
          rich_text: [
            {
              text: {
                content: track.album
              }
            }
          ]
        },
        'Duration': {
          number: track.duration
        },
        'Popularity': {
          number: track.popularity
        },
        'External_URL': {
          url: track.external_url
        },
        'Key': {
          rich_text: [
            {
              text: {
                content: track.key.toString()
              }
            }
          ]
        },
        'Mode': {
          rich_text: [
            {
              text: {
                content: track.mode.toString()
              }
            }
          ]
        },
        'Tempo': {
          number: track.tempo
        },
        'Danceability': {
          number: track.danceability
        }
      }
    });
  } catch (error) {
    console.error('Error adding to Notion database:', error);
  }
}

module.exports = { addToNotionDatabase };

Step 8 - Main Script

Create a main.js file that uses the modules created above to execute the integration logic.
JavaScript
require('dotenv').config();

const { getSpotifyPlaylistTracks } = require('./integrations/spotifyIntegration');
const { addToNotionDatabase } = require('./integrations/notionIntegration');

const NOTION_DATABASE_ID = process.env.NOTION_DATABASE_ID;
const SPOTIFY_PLAYLIST_ID = process.env.SPOTIFY_PLAYLIST_ID;

// Main function to fill the Notion database with Spotify playlist data
async function fillNotionDatabase() {
  const tracks = await getSpotifyPlaylistTracks(SPOTIFY_PLAYLIST_ID);

  for (const track of tracks) {
    await addToNotionDatabase(NOTION_DATABASE_ID, track);
    console.log(`Added to Notion: Title: ${track.title}, Artist: ${track.artist}, Album: ${track.album}`);
  }
}

fillNotionDatabase();

Step 9 - Run the Integration

Execute the integration script by running the following command:
Shell
npm start
Customize the code to match your Notion database structure and desired track properties. Handle pagination for large playlists.