> ## Documentation Index
> Fetch the complete documentation index at: https://developers.notion.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sync Spotify Playlist with Notion

> This developer documentation provides a step-by-step guide to create a connection between the Notion API and the Spotify API using JavaScript. The connection fetches data from a Spotify playlist and populates a Notion database with track metadata, including musical properties.

export const developerConnectionsUrl = "https://app.notion.com/developers/connections";

## Prerequisites

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

## Step 1 - Get Your API Keys

**Spotify API Key**

<Steps>
  <Step>
    Log in to your Spotify Developer account.
  </Step>

  <Step>
    Go to the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/applications).
  </Step>

  <Step>
    Click on **Create an App**.
  </Step>

  <Step>
    Fill in the required details and click **Create**.
  </Step>

  <Step>
    Copy the **Client ID** and **Client Secret**.
  </Step>
</Steps>

**Notion API Key**

<Steps>
  <Step>
    Log in to your Notion account.
  </Step>

  <Step>
    Go to <a href={developerConnectionsUrl}>Notion Connections</a>.
  </Step>

  <Step>
    Click on **New Connection**.
  </Step>

  <Step>
    Fill in the required details and click **Submit**.
  </Step>

  <Step>
    Copy the generated **Installation access token**.
  </Step>
</Steps>

## Step 2 - Set Up Your Notion Database

<Steps>
  <Step>
    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)
  </Step>

  <Step>
    Share the database with your connection:

    * Click on the three dots in the top-right corner of the page.
    * Under **Connections**, click on **Connect to** and search for your connection and connect to it.
  </Step>
</Steps>

## Step 3 - Project Structure

This step is not necessary but we suggest projects to be structured like so:

```shell theme={null}
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 YAML theme={null}
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:

```bash Shell theme={null}
npm install @notionhq/client dotenv
```

Create a `package.json` file and add the following:

```json JSON theme={null}
{
    "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 JavaScript expandable theme={null}
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 JavaScript theme={null}
// 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 Connections

Create `spotifyIntegration.js` to fetch tracks from a Spotify playlist.

```javascript JavaScript expandable theme={null}
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 JavaScript expandable theme={null}
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 connection logic.

```javascript JavaScript expandable theme={null}
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 Connection

Execute the connection script by running the following command:

```shell Shell theme={null}
npm start
```

<Warning>
  Customize the code to match your Notion database structure and desired track properties. Handle pagination for large playlists.
</Warning>
