This developer documentation provides a step-by-step guide to create an integration between the Notion API and the Spotify API using JavaScript. The integration fetches data from a Spotify playlist and populates a Notion database with track metadata, including musical properties.
Spotify API Key
Notion API Key
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
Create a .env
file and populate with the following information:
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'
Install the required Node.js packages using the following command:
npm install @notionhq/client dotenv
Create a package.json
file and add the following:
{
"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",
}
}
Create a spotify.js
file to set up the Spotify API client.
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.
// 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 };
Create spotifyIntegration.js
to fetch tracks from a Spotify playlist.
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.
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 };
Create a main.js
file that uses the modules created above to execute the integration logic.
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();
Execute the integration script by running the following command:
🔑Customize the code to match your Notion database structure and desired track properties. Handle pagination for large playlists.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4