Abgespielte Songs mit der Spotify Web API auslesen
Mein Ziel war es meinen zuletzt auf Spotify gehörten Song auf meiner Website anzeigen zu können. Dank der Spotify Web API ein Kinderspiel!
tl;dr
Spotify bietet die Möglichkeit, mit der Spotify Web API an viele Daten aus dem eigenen Spotify Account zu kommen. Unter anderem auch an eine Liste der zuletzt gehörten Tracks. Der Zugang ist jedoch an den jeweiligen Account gekoppelt und natürlich auch nur mit entsprechender Authentifizierung möglich.
Wie bekommt man das Ganze also auf die Website? – Mit einem kleinen, eigenen Backend als Proxy! So sind die persönlichen Tokens nicht von außen abrufbar. Das wäre nämlich überhaupt keine gute Idee ;-)
Die Idee 💡
Während ich entwickle, höre ich oft Musik, um möglichst tief in den berühmten "Tunnel" zu kommen. Also in einen Zustand maximaler Konzentration. Mir kam der Gedanke, dass es ganz interessant wäre, ein kleines Widget auf meine Website zu bringen, das meine zuletzt gehörte Musik anzeigt. Am besten natürlich mit Cover und direktem Link zu Spotify.
Da mir Design und UX ziemlich wichtig sind, sollte sich die Lösung nahtlos in meine Website integrieren. Etwaige Drittanbieter-Lösungen fielen damit eigentlich schon raus. Es sollte also am besten eine Schnittstelle her, die ich mit ansprechen und die zurückgegeben Daten in einer React-Komponente (ich nutze für meine Website nämlich Gatsby) rendern kann.
Die Rettung: Spotify hat eine API!
Zugegeben, es hätte mich gewundert, wenn es nicht so wäre: Spotify bietet natürlich eine API an, um genau an die benötigten Informationen zu kommen, die mich interessieren.
Es gibt dabei zwei Hürden, die gemeistert werden wollen:
- Es wird eine eigene App im Developer Portal benötigt
- Die API verlangt eine Authentifizierung über den jeweiligen Spotify Account
Der erste Punkt ist relativ schnell erledigt. Dazu meldest du dich im Developer Portal von Spotify an und erstellst die entsprechende App.
Der zweite Punkt ist etwas umfangreicher, zumindest wenn man die Informationen auf der Website nutzen möchte. Spotify setzt als Authentifizierungsmethode verschiedene OAuth 2.0 Flows voraus. Die einzig sinnvolle in unserem Kontext ist die mittels Authorization Code. Darüber erhalten wir sowohl einen kurzlebigen Access Token, als auch einen im Prinzip unbegrenzt lang gültigen Refresh Token, mit dem ich mir wiederum einen frischen Access Token erzeugen lassen kann.
Das heißt zusammengefasst: So lange wie ich meinen Spotify Account mit der eigenen OAuth-App verbunden habe, so lange kann ich auch Daten darüber abrufen. Perfekt!
Proxy for the win
Ein kurzer Recap: Es gibt eine API, wir kommen an entsprechende Tokens zur Authentifizierung und wir wollen die Daten auf eine Website bringen.
Moment... Tokens, die Zugriff auf meinen Account haben, möchte ich aber nicht mit der Welt teilen. 🤔
– Richtig. Damit lässt sich bekanntlich allerhand Schabernack treiben und da ich nicht möchte,
dass mir jemand Helene Fischer in meine Playlist schmeißt, muss das Ganze gegen schlechten Geschmack unbefugten Zugriff abgesichert werden ;-)
Kurzerhand habe ich mir einen kleinen Proxy für die API geschrieben, der die gesamte Kommunikation mit Spotify im Hintergrund abwickelt und keine Tokens nach außen preisgibt.
Dieser kennt meinen Refresh Token und kann – wenn nötig – einen neuen Access Token erzeugen. Damit spreche ich wiederum die Spotify API an und gebe das Resultat über einen eigenen Endpunkt zurück.
Gelöst werden kann das zum Beispiel über einen kleinen node.js-Prozess, der per Express einen Endpunkt zur Verfügung stellt und den zuletzt gespielten Titel als JSON wiedergibt. Im Prinzip habe ich das auch so gelöst, allerdings innerhalb einer Serverless Function bei vercel.
Hier findest du ein GitHub Gist als Code-Beispiel.
Problem solved. 🎉
Fazit
Nochmal alle Informationen zusammengefasst:
Spotify bietet eine tolle API, mit der man noch eine Menge mehr anstellen kann, als ich es für diesen Fall benötigt habe. Je nachdem wo man die Daten verarbeiten oder anzeigen möchte, muss man jedoch kleine Umwege zugunsten der Sicherheit in Kauf nehmen.