Son zamanlarda bazı blogları gezerken insanların sitelerine Spotify’da o an ne dinlediklerini gösteren bir araç eklemeye başladıklarını gördüm. Bu sitelerin çoğu React ile yapıldığı için kendi 11ty siteme eklemeye kalktığımda ortalık biraz kirlenmeye başlıyordu. Haliyle kendi çözümümü aramaya başladım. İnternet’ten bulduğum bir kaç örneği birleştirip aşağıdaki gibi bir şey yaptım.

Başlamadan önce aşağıdaki komut ile sitemizde kullanacağımız npm paketlerini ekliyoruz. Ben paket yöneticisi olarak yarn kullanıyorum, siz dilerseniz npm ile yüklersiniz.

yarn add @netlify/functions spotify-web-api-node

Üç adet dosya oluşturacağız. Birincisi Netlify Fonksiyonu için:

const { getSecrets, Handler } = require("@netlify/functions");
const SpotifyWebApi = require("spotify-web-api-node")

module.exports.handler = async function handler(event, context) {
const spotifyApi = new SpotifyWebApi();

const secrets = await getSecrets(event);
if (secrets.spotify) {
spotifyApi.setAccessToken(secrets.spotify.bearerToken)

const currentTrack = await spotifyApi.getMyCurrentPlayingTrack()

const response = {
href: currentTrack.body.item?.external_urls?.spotify,
name: currentTrack.body.item?.name,
artist: currentTrack.body.item?.artists[0]?.name,
cover: currentTrack.body.item?.album?.images[2]?.url
}

if (currentTrack) {
return {
statusCode: 200,
body: JSON.stringify(response)
}
}
return {
statusCode: 400,
body: JSON.stringify({
error: "failed to read playing track"
})
}
} else {
return {
statusCode: 401,
body: "You can't access this"
}
}
}

Bu dosyayı projemizin kök klasörünün içerisinde .netlify/functions klasöründe tutmamız gerekiyor, örneğin .netlify/functions/now-playing/now-playing.js gibi. Bu kodun çalışabilmesi için Netlify üzerinden Graph kısmına girip Config‘e girerek API Authentication bölümünden Spotify girişini yapmanız gerekiyor. Fonksiyon çalıştığında bize cevap olarak çalan şarkını linkini (href), adını (name), sanatçısını (artist) ve albüm kapağını (cover) verecek. Daha fazlasını eklemek isterseniz currentTrack.body.item ile gelen JSON kodunu inceleyip istediğiniz kısımlarını ekleyebilirsiniz.

Daha sonrasında bu fonksiyondan gelen cevabı işleyip kullanacağımız scripti ekliyoruz. Bu dosyayı sitemizin içerisinden çağıracağımız için kendi düzeninize göre bir yere kaydedin. Ben tüm stilleri, scriptleri ve yazı tiplerini assets diye bir klasörde sakladığım için src/assets/js/now-playing.js olarak kaydediyorum. Gelelim scriptimize;

async function renderContent() {
const title = document.getElementById("now-playing-title");
const artist = document.getElementById("now-playing-artist");
const cover = document.getElementById("now-playing-cover");

fetch("/.netlify/functions/now-playing")
.then((response) => {
if (response.status !== 200) {
throw new Error(`HTTP status ${response.status}`);
} else {
return response.json();
}
})
.then((json) => {
if(typeof json.href !== "undefined") {
title.classList.remove("not-playing");
title.setAttribute("href", json.href);
title.textContent = json.name;
artist.textContent = json.artist;
cover.src = json.cover;
}
})
.catch(() => null);
}

renderContent();

Burada eğer fonksiyon yanıt verirse gelen sonucu sitemizdeki #now-playing-title , #now-playing-artist ve #now-playing-cover kimliğine sahip kısımlara ekliyor. Tabi sitemizde bu alanların olması gerekiyor. Bunun için de hazırlayacağımız son dosyaya geliyoruz. Bunun için ayrı bir dosya da hazırlayıp çağırabilirsiniz, direkt hazır olan şablonunuzda göstereceğiniz kısma da ekleyebilirsiniz, size kalmış.

<script type="module" src="/assets/js/now-playing.js"></script>
<section class="now-playing" title="Spotify'da şu an dinlediğim şarkı.">
<img id="now-playing-cover" src="/img/cover.webp" alt="Cover placeholder" width="48" height="48">
<span>
<a id="now-playing-title" class="not-playing" href="#" target="_blank" rel="noreferrer noopener">Bir şey dinlemiyorum...</a>
<p id="now-playing-artist">Spotify</p>
</span>
</section>

Ben bunu src/_includes/partials/nowplaying.njk olarak kaydettim ve src/_includes/layouts/home.njk üzerinden çağırıyorum sadece anasayfamda gösterdiğim için.

Hepsi bu kadar.