mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
242 lines
6.5 KiB
JavaScript
242 lines
6.5 KiB
JavaScript
import axios from "axios"
|
|
import { DateTime } from "luxon"
|
|
|
|
const TIDAL_CLIENT_ID = process.env.TIDAL_CLIENT_ID
|
|
const TIDAL_CLIENT_SECRET = process.env.TIDAL_CLIENT_SECRET
|
|
|
|
export default class TidalAPI {
|
|
static async checkAuthStatus(device_code) {
|
|
const data = {
|
|
"client_id": TIDAL_CLIENT_ID,
|
|
"device_code": device_code,
|
|
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
|
|
"scope": "r_usr+w_usr+w_sub"
|
|
}
|
|
|
|
const response = await axios({
|
|
method: "POST",
|
|
url: "https://auth.tidal.com/v1/oauth2/token",
|
|
params: data,
|
|
auth: {
|
|
username: TIDAL_CLIENT_ID,
|
|
password: TIDAL_CLIENT_SECRET
|
|
}
|
|
}).catch((err) => {
|
|
return false
|
|
})
|
|
|
|
if (!response) {
|
|
return false
|
|
}
|
|
|
|
return response.data
|
|
}
|
|
|
|
static async getAuthUrl() {
|
|
let data = {
|
|
client_id: TIDAL_CLIENT_ID,
|
|
scope: "r_usr+w_usr+w_sub"
|
|
}
|
|
|
|
const response = await axios({
|
|
method: "POST",
|
|
url: "https://auth.tidal.com/v1/oauth2/device_authorization",
|
|
params: data
|
|
})
|
|
|
|
return {
|
|
url: "https://" + response.data.verificationUri + "/" + response.data.userCode,
|
|
device_code: response.data.deviceCode,
|
|
expires_in: response.data.expiresIn
|
|
}
|
|
}
|
|
|
|
static async getUserData({
|
|
access_token,
|
|
user_id,
|
|
country
|
|
}) {
|
|
const url = `https://api.tidal.com/v1/users/${user_id}?countryCode=${country}`
|
|
|
|
const response = await axios({
|
|
method: "GET",
|
|
url,
|
|
headers: {
|
|
"Origin": "http://listen.tidal.com",
|
|
Authorization: `Bearer ${access_token}`
|
|
}
|
|
})
|
|
|
|
return response.data
|
|
}
|
|
|
|
static async getTrackPlaybackUrl({
|
|
track_id,
|
|
quality,
|
|
access_token,
|
|
}) {
|
|
let data = {
|
|
soundQuality: quality ?? "LOSSLESS",
|
|
}
|
|
|
|
const response = await axios({
|
|
method: "GET",
|
|
url: `https://api.tidal.com/v1/tracks/${track_id}/streamUrl`,
|
|
params: data,
|
|
headers: {
|
|
"Origin": "http://listen.tidal.com",
|
|
Authorization: `Bearer ${access_token}`
|
|
}
|
|
})
|
|
|
|
return response.data
|
|
}
|
|
static async getTrackMetadata({
|
|
track_id,
|
|
access_token,
|
|
country,
|
|
}) {
|
|
const response = await axios({
|
|
method: "GET",
|
|
url: `https://api.tidal.com/v1/tracks/${track_id}/?countryCode=${country}`,
|
|
headers: {
|
|
"Origin": "http://listen.tidal.com",
|
|
Authorization: `Bearer ${access_token}`
|
|
}
|
|
})
|
|
|
|
return response.data
|
|
}
|
|
|
|
static async getTrackManifest({
|
|
track_id,
|
|
quality,
|
|
access_token,
|
|
country,
|
|
}) {
|
|
const playback = await TidalAPI.getTrackPlaybackUrl({
|
|
track_id,
|
|
quality,
|
|
access_token,
|
|
country,
|
|
})
|
|
|
|
const metadata = await TidalAPI.getTrackMetadata({
|
|
track_id,
|
|
access_token,
|
|
country,
|
|
})
|
|
|
|
return {
|
|
playback,
|
|
metadata
|
|
}
|
|
}
|
|
|
|
static async search({
|
|
query,
|
|
type = "all"
|
|
}) {
|
|
let url = `https://api.tidal.com/v1/search`
|
|
|
|
switch (type) {
|
|
case "all":
|
|
url = `https://api.tidal.com/v1/search`
|
|
break
|
|
case "playlists":
|
|
url = `https://api.tidal.com/v1/search/playlists`
|
|
break
|
|
case "artists":
|
|
url = `https://api.tidal.com/v1/search/artists`
|
|
break
|
|
case "albums":
|
|
url = `https://api.tidal.com/v1/search/albums`
|
|
break
|
|
case "tracks":
|
|
url = `https://api.tidal.com/v1/search/tracks`
|
|
break
|
|
}
|
|
|
|
const response = await axios({
|
|
method: "GET",
|
|
url: url,
|
|
params: {
|
|
query: query,
|
|
countryCode: "AZ"
|
|
},
|
|
headers: {
|
|
"Origin": "http://listen.tidal.com",
|
|
"x-tidal-token": TIDAL_CLIENT_ID
|
|
}
|
|
})
|
|
|
|
return response.data.tracks.items.map((item) => {
|
|
item._id = item.id
|
|
|
|
const coverUID = item.album.cover.replace(/-/g, "/")
|
|
|
|
item.cover = `https://resources.tidal.com/images/${coverUID}/1280x1280.jpg`
|
|
|
|
item.artist = item.artists.map(artist => artist.name).join(", ")
|
|
|
|
item.metadata = {
|
|
title: item.title,
|
|
artists: item.artists.map(artist => artist.name).join(", "),
|
|
artist: item.artists.map(artist => artist.name).join(", "),
|
|
album: item.album.title,
|
|
duration: item.duration
|
|
}
|
|
|
|
item.service = "tidal"
|
|
|
|
return item
|
|
})
|
|
}
|
|
static async getFavoriteTracks({
|
|
user_id,
|
|
country,
|
|
access_token,
|
|
}) {
|
|
const url = `https://api.tidal.com/v1/users/${user_id}/favorites/tracks?countryCode=${country}`
|
|
|
|
const response = await axios({
|
|
method: "GET",
|
|
url,
|
|
headers: {
|
|
"Origin": "http://listen.tidal.com",
|
|
Authorization: `Bearer ${access_token}`
|
|
},
|
|
params: {
|
|
order: "DATE",
|
|
orderDirection: "DESC"
|
|
}
|
|
})
|
|
|
|
return response.data.items.map((item) => {
|
|
// get js time
|
|
item.item.liked_at = new Date(item.created).getTime()
|
|
item.item.service = "tidal"
|
|
|
|
item.item._id = item.item.id
|
|
|
|
const coverUID = item.item.album.cover.replace(/-/g, "/")
|
|
|
|
item.item.cover = `https://resources.tidal.com/images/${coverUID}/1280x1280.jpg`
|
|
|
|
item.item.artist = item.item.artists.map(artist => artist.name).join(", ")
|
|
|
|
item.item.metadata = {
|
|
title: item.item.title,
|
|
artists: item.item.artists.map(artist => artist.name).join(", "),
|
|
artist: item.item.artists.map(artist => artist.name).join(", "),
|
|
album: item.item.album.title,
|
|
duration: item.item.duration
|
|
}
|
|
|
|
item.item.liked = true
|
|
item.item._computed = true
|
|
|
|
return item.item
|
|
})
|
|
}
|
|
} |