├── .gitignore ├── .dockerignore ├── .DS_Store ├── package.json ├── Dockerfile └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_store 3 | .env -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | .env -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmfunc/spotify-api-service/main/.DS_Store -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "cors": "^2.8.5", 4 | "dotenv": "^16.0.3", 5 | "express": "^4.18.2", 6 | "nodemon": "^2.0.20" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:19 2 | 3 | # Create app directory 4 | WORKDIR /usr/src/app 5 | 6 | # Install app dependencies 7 | # A wildcard is used to ensure both package.json AND package-lock.json are copied 8 | # where available (npm@5+) 9 | COPY package*.json ./ 10 | 11 | RUN npm install 12 | # If you are building your code for production 13 | # RUN npm ci --only=production 14 | 15 | # Bundle app source 16 | COPY . . 17 | 18 | # Expose our app's port to the docker daemon 19 | EXPOSE 8080 20 | 21 | CMD [ "node", "index.js" ] -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const cors = require('cors'); 4 | const querystring = require("node:querystring"); 5 | require("dotenv").config(); 6 | 7 | const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`; 8 | const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`; 9 | const client_id = process.env.CLIENT_ID; 10 | const client_secret = process.env.CLIENT_SECRET; 11 | const refresh_token = process.env.REFRESH_TOKEN; 12 | 13 | app.use(cors({ 14 | origin: ['https://www.samlinville.com', 'https://samlinville.com'] 15 | })); 16 | 17 | const ingredients = [ 18 | { 19 | "id": "1", 20 | "item": "Bread" 21 | }, 22 | { 23 | "id": "2", 24 | "item": "Eggs" 25 | }, 26 | { 27 | "id": "3", 28 | "item": "Milk" 29 | }, 30 | { 31 | "id": "4", 32 | "item": "Butter" 33 | }, 34 | ]; 35 | 36 | app.get('/spotify/current', async (req, res) => { 37 | var nowPlaying = await getNowPlayingItem(client_id, client_secret, refresh_token) 38 | if (nowPlaying !== false) { 39 | res.status(200).send({ message: nowPlaying }); 40 | } else { 41 | res.status(400).send({ message: 'No data' }); 42 | } 43 | } 44 | ); 45 | app.listen(8080); 46 | 47 | 48 | const getAccessToken = async () => { 49 | const basic = Buffer.from(`${client_id}:${client_secret}`).toString("base64"); 50 | const response = await fetch(TOKEN_ENDPOINT, { 51 | method: "POST", 52 | headers: { 53 | Authorization: `Basic ${basic}`, 54 | "Content-Type": "application/x-www-form-urlencoded", 55 | }, 56 | body: querystring.stringify({ 57 | grant_type: "refresh_token", 58 | refresh_token, 59 | }), 60 | }); 61 | return response.json(); 62 | }; 63 | 64 | const getNowPlaying = async (client_id, client_secret, refresh_token) => { 65 | const { access_token } = await getAccessToken( 66 | client_id, 67 | client_secret, 68 | refresh_token 69 | ); 70 | 71 | return fetch(NOW_PLAYING_ENDPOINT, { 72 | headers: { 73 | Authorization: `Bearer ${access_token}`, 74 | }, 75 | }); 76 | }; 77 | 78 | async function getNowPlayingItem(client_id, client_secret, refresh_token) { 79 | const response = await getNowPlaying(client_id, client_secret, refresh_token); 80 | if (response.status === 204 || response.status > 400) { 81 | return false; 82 | } 83 | 84 | const song = await response.json(); 85 | const albumImageUrl = song.item.album.images[0].url; 86 | const artist = song.item.artists.map((_artist) => _artist.name).join(", "); 87 | const isPlaying = song.is_playing; 88 | const songUrl = song.item.external_urls.spotify; 89 | const title = song.item.name; 90 | 91 | return { 92 | albumImageUrl, 93 | artist, 94 | isPlaying, 95 | songUrl, 96 | title, 97 | }; 98 | } --------------------------------------------------------------------------------