This is an unofficial spotify package written for Typecript and JavaScript to interact with its public and oAuth API. Everything is tested with Visual Studio Code, node.js 21 or greater and Typescript (ESM, compiled to ES2016 - ES2022, CommonJS).
If you need help using this package, join our Discord Server.
Download this npm package to use in your project with the following commands:
If you run node.js v18 or higher, use
# With npm
npm install lunify.js
# With yarn
yarn add lunify.js
# With pnpm
pnpm add lunify.js
node.js v17 or lower is currently not supported.
All examples are written for TypeScript, if you use JavaScript please use the commonJS import method. Please note that every update could contain breaking changes during 0.x.x phase.
This is essential for everything you want to do with this package, get your client id and client secrent from the spotify developers dashboard, don't forget to keep the secret a secret :)
import { Lunify } from 'lunify.js';
const api = new Lunify({
clientId: '898e127e95f24f578fdbfec93ae203cd',
clientSecret: 'dc302ea39cefbdf875f42f59e721e898',
// If you want to have access to oauth2
oauth: {
redirectUri: 'http://10.0.0.50:7654/callback'
}
});
You can generate a url for users to login like shown bellow, learn more about for what you need scopes here, if you are unsure what scopes you need for what, use the spotify docs references.
const url = api.oauth.generateUrl([Scopes.Streaming, Scopes.UserModifyPlaybackState, Scopes.UserReadPlaybackState]);
From the callback urls query params you get a code
with is used to fetch users access token from spotify.
const access = await api.oauth.fetchToken(code);
If you want to just play music or do other things with a user's player, you can create a PartialUser like that:
const user = new PartialUser(api, access);
user.player.play("4cOdK2wGLETKBW3PvgPWqT");
If you want to access to user's data you can just get it from the previously gotten access class
const user = await access.fetchUser();
user.player.play("4cOdK2wGLETKBW3PvgPWqT");
console.log(user.displayName)
Getting a single track, note that all fetched data gets cached to not spam the api as much
const track = await api.tracks.fetch("4cOdK2wGLETKBW3PvgPWqT");
// or if you want to skip the cache
const track = await api.tracks.fetch("4cOdK2wGLETKBW3PvgPWqT", { force: true });
import fastify from 'fastify';
import { Lunify, UserOauth, Scopes, PartialUser } from 'lunify.js';
const app = fastify();
const api = new Lunify({
clientId: '898e127e95f24f578fdbfec93ae203cd',
clientSecret: 'dc302ea39cefbdf875f42f59e721e898',
oauth: {
redirectUri: 'http://localhost:3000/callback'
}
});
// Login and authorize this app to access your spotify account
// GET http://localhost:3000/login
app.get('/login', (req, res) => {
const url = api.oauth.generateUrl([Scopes.Streaming, Scopes.UserModifyPlaybackState, Scopes.UserReadPlaybackState]);
res.redirect(url);
});
let access: UserOauth | undefined;
// Callback to get your authorization code and fetch your user credentials (NOT spotify login credentials)
// GET http://localhost:3000/callback
app.get('/callback', async (req) => {
const code = (req.query as Record<string, string>).code || null;
const state = (req.query as Record<string, string>).state || null;
const error = (req.query as Record<string, string>).error || null;
if (error) return error;
if (!state) return 'Invalud state';
access = await api.oauth.fetchToken(code);
console.log(access)
return 'OK';
});
// Play a track on your current device, provide a track as query param (don't forget to remove all of spotifies tracking queries from their links)
// GET http://localhost:3000/play?track=https://open.spotify.com/track/0ZVjgfaC2Ptrod9v6p9KFP
app.get('/play', (req) => {
if (!access) return "You need to go to /login first"
const track = (req.query as Record<string, string>).track?.split('/track/')?.[1]?.split('?')[0];
if (!track) return 'No track id';
// We use PartialUser so we do not have to fetch user data to use it's player
const user = new PartialUser(api, access);
user.player.play(track);
return 'OK';
});
// Get your user data
// GET http://localhost:3000/me
app.get('/me', async () => {
if (!access) return "You need to go to /login first"
const user = await access.fetchUser();
console.log(user);
return 'OK';
});
// Fetch a track, provide a track as query param (don't forget to remove all of spotifies tracking queries from their links)
// GET http://localhost:3000/track?track=https://open.spotify.com/track/0ZVjgfaC2Ptrod9v6p9KFP
app.get('/track', async (req) => {
const trackId = (req.query as Record<string, string>).track?.split('/track/')?.[1]?.split('?')[0];
if (!trackId) return 'No track id';
const track = await api.tracks.fetch(trackId);
console.log(track);
return 'OK';
});
// Let the webserver listen to that port
app.listen({ host: 'localhost', port: 3000 }, (err, address) => {
if (err) console.log(err);
console.log(`Listening to ${address}`);
});
Read the code or use your IDEs intellisense :)