DiscoverWeeklyCollector
This project was based on https://ahmetomer.net/spotify-api-authorization-in-nodejs/
Why did I make this?
I don't always listen to my Discover Weekly Playlist and it resets every week with new tracks. I wanted to create a way to archive the songs so I could go back to listen to them in the future. That's when I had the idea to stitch this project together.
How Does it work and what does it do?
- It creates a
frontendserver that listens forGETrequest at the root. i.e.http://localhost:3000/- This is essentially a dummy page so that the process can finish properly
- It creates a
backendserver that listes forGETrequest onhttp://localhost:8888/api/login- When the page loads it will
redirectthe browser to an authorization page for Spotify.
- When the page loads it will
GETrequest onhttp://localhost:8888/api/logged- After the user get's authenticated and accepts the app, this is where the browser redirects us to.
- When the page loads it will programatically reach out to spotify and get an
access_tokenwhich it will then use to- Get the tracks from the
Discover Weekly Playlistand - Add them to the
Discover Weekly Playlist Aggregator
- Get the tracks from the
- It runs puppeteer in headless mode
- Opens a web browser and navigates to
http://localhost:8888/api/login - When the Authorization Page from Spotify loads, it enters the user's credentials and clicks
Submit - It then waits until the browser navigates to a new url (
http://localhost:3000/)http://localhost:8888/api/loggedcounts as a browser redirect, not as a new url
- Opens a web browser and navigates to
- By the time
http://localhost:3000/is loaded, all of the logic has been executed and since puppeteer exits successfully with code 0, it kills the rest of the servers (frontend, andbackend) because of--kill-others --success lastinconcurrently \"npm:start:frontend\" \"npm:start:backend\" \"npm:start:puppeteer\" --kill-others --success last
ENVIRONMENT VARIABLE SAMPLE FILE
necessary environment variables for .env file
# FRONTEND
FRONTEND_PORT=3000
# BACKEND
BACKEND_PORT=8888
CLIENT_ID=
CLIENT_SECRET=
REDIRECTURI="http://localhost:8888/api/logged"
CLIENT_REDIRECTURI="http://localhost:3000/"
DISCOVER_WEEKLY_PLAYLIST_ID=
DISCOVER_WEEKLY_AGGREGATOR_PLAYLIST_ID=
# PUPPETEER
SPOTIFY_USERNAME=
SPOTIFY_PASSWORD=
SETUP
- Clone repository
- Install and use
Node v18.16.1 - Run
npm install - At the root of the repository create a file called
.env. Use the one in ENVIRONMENT VARIABLE SAMPLE FILE - Register a Spotify App and get a token by following the Spotify App instructions from https://ahmetomer.net/spotify-api-authorization-in-nodejs/
- MAKE SURE TO ADD THE CORRECT REDIRTECT URL TO THE SPOTIFY APP! (
http://localhost:8888/api/logged) - You will get
CLIENT_IDandCLIENT_SECRETfrom this step
- MAKE SURE TO ADD THE CORRECT REDIRTECT URL TO THE SPOTIFY APP! (
- Go to the spotify player and crete a new playlist called
DISCOVER WEEKLY AGGREGATORor something like that. - Get the link to the playlist by clicking on the
Ellipsis->Share->Copy link to playlist.- You should now have a URL that looks like this
https://open.spotify.com/playlist/5EIjIqnxsxQrlms9XSWhEs?si=0025a51a60fa427b - The playlist id is what comes immediataly after
playlist/in this case it is5EIjIqnxsxQrlms9XSWhEs
- You should now have a URL that looks like this
- REPLACE
DISCOVER_WEEKLY_AGGREGATOR_PLAYLIST_IDwith your playlist id (i.e.5EIjIqnxsxQrlms9XSWhEs) - Get the playlist id of your
Discover Weekly Playlistor whatever playlist you want to copy the songs from- REPLACE
DISCOVER_WEEKLY_PLAYLIST_IDwith your playlist id (i.e.12344UIEYJHhu123)
- REPLACE
- Update
SPOTIFY_USERNAMEandSPOTIFY_PASSWORDacordingly. - The app is ready!
RUN IT
- Run
npm run aggregator- This will run
"npm:start:frontend" "npm:start:backend" "npm:start:puppeteer"concurrently and will exit when it's done
- This will run
- Your playlist should now be updated!
Example output
> discoverweeklycollector@1.0.0 aggregator
> concurrently "npm:start:frontend" "npm:start:backend" "npm:start:puppeteer" --kill-others --success last
[start:puppeteer]
[start:puppeteer] > discoverweeklycollector@1.0.0 start:puppeteer
[start:puppeteer] > node puppeteer/index.js
[start:puppeteer]
[start:backend]
[start:backend] > discoverweeklycollector@1.0.0 start:backend
[start:backend] > node backend/index.js
[start:backend]
[start:frontend]
[start:frontend] > discoverweeklycollector@1.0.0 start:frontend
[start:frontend] > node frontend/index.js
[start:frontend]
[start:frontend] Frontend server started on port 3000
[start:backend] Backend server started on port 8888
[start:puppeteer] === START PUPPETEER ===
[start:puppeteer]
[start:puppeteer] Puppeteer old Headless deprecation warning:
[start:puppeteer] In the near feature `headless: true` will default to the new Headless mode
[start:puppeteer] for Chrome instead of the old Headless implementation. For more
[start:puppeteer] information, please see https://developer.chrome.com/articles/new-headless/.
[start:puppeteer] Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
[start:puppeteer] If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.
[start:puppeteer]
[start:backend] === BACKEND - LOGIN ===
[start:backend] === BACKEND - REDIRECT ===
[start:backend] === BACKEND - AUTHENTICATING WITH SPOTIFY ===
[start:backend] === BACKEND - GET DISCOVER WEEKLY PLAYLIST ===
[start:backend] === BACKEND - ADD TRACKS TO DISCOVER WEEKLY AGGREGATOR ===
[start:backend] === BACKEND - ADDED THE FOLLOWING SONGS TO THE PLAYLIST ===
[start:backend]
[start:backend] Daft Punk, Julian Casablancas, The Voidz - Infinity Repeating (2013 Demo) [feat. Julian Casablancas+The Voidz]
[start:backend] Daft Punk - One More Time
[start:backend] Daft Punk, Pharrell Williams, Nile Rodgers - Get Lucky (feat. Pharrell Williams and Nile Rodgers)
[start:backend] Daft Punk - Around the World
[start:backend] Daft Punk, Todd Edwards - The Writing of Fragments of Time (feat. Todd Edwards)
[start:backend] Daft Punk, Todd Edwards - Fragments of Time (feat. Todd Edwards)
[start:backend] Daft Punk - Harder, Better, Faster, Stronger
[start:backend] Daft Punk, Pharrell Williams - Lose Yourself to Dance (feat. Pharrell Williams)
[start:backend] Daft Punk - Something About Us
[start:backend] Daft Punk - GLBTM (Studio Outtakes)
[start:backend] Daft Punk - Give Life Back to Music
[start:backend] Daft Punk, Julian Casablancas - Instant Crush (feat. Julian Casablancas)
[start:backend] The Weeknd, Daft Punk - I Feel It Coming
[start:backend] Daft Punk, Panda Bear - Doin' it Right (feat. Panda Bear)
[start:backend] Daft Punk - Veridis Quo
[start:backend] Daft Punk - Giorgio by Moroder
[start:backend] Daft Punk - Da Funk
[start:backend] Daft Punk, Paul Williams - Touch (feat. Paul Williams)
[start:backend] Daft Punk - End of Line
[start:backend] Daft Punk - Digital Love
[start:backend] Daft Punk - The Game of Love
[start:backend] Daft Punk - Revolution 909
[start:backend] Daft Punk - Technologic
[start:backend] Daft Punk - Burnin'
[start:backend] The Weeknd, Daft Punk - Starboy
[start:backend] Daft Punk - Fresh
[start:backend] Daft Punk - Robot Rock
[start:backend] Daft Punk - Teachers
[start:backend] Daft Punk - Voyager
[start:backend] Daft Punk - Rollin' & Scratchin'
[start:backend] Daft Punk - Human After All
[start:backend] Daft Punk, Ian Pooley - Burnin' - Ian Pooley Cut up Mix
[start:backend] Daft Punk - Derezzed
[start:backend] Daft Punk - Aerodynamic
[start:backend] Daft Punk - Make Love
[start:backend] Daft Punk - Face to Face
[start:backend] Daft Punk - The Prime Time of Your Life
[start:backend] Daft Punk - High Life
[start:backend] Daft Punk - Television Rules the Nation
[start:backend] Daft Punk - The Son of Flynn
[start:backend] Daft Punk, DJ Sneak - Burnin' - DJ Sneak Main Mix
[start:backend] Daft Punk - Face to Face
[start:backend] Daft Punk, Masters At Work - Around the World - Kenlou Mix
[start:backend]
[start:backend] === BACKEND - FINISHED WITH ~~SUCCESS~~ ===
[start:frontend] === FRONTEND - SUCCESS ===
[start:puppeteer] === END PUPPETEER ===
[start:puppeteer] npm run start:puppeteer exited with code 0
--> Sending SIGTERM to other processes..
[start:frontend] npm run start:frontend exited with code 1
--> Sending SIGTERM to other processes..
[start:backend] npm run start:backend exited with code 1