diff --git a/src/streamers/tidal/main.ts b/src/streamers/tidal/main.ts index 9de6ac0..cb563f2 100644 --- a/src/streamers/tidal/main.ts +++ b/src/streamers/tidal/main.ts @@ -28,6 +28,7 @@ interface TidalOptions { accessToken: string refreshToken: string expires: number + countryCode: string } interface LoginData { @@ -37,12 +38,17 @@ interface LoginData { expires_in: number } +interface SessionData { + countryCode: string +} + export default class Tidal implements Streamer { tvToken: string tvSecret: string accessToken: string refreshToken: string expires: number + countryCode: string hostnames = ['tidal.com', 'www.tidal.com', 'listen.tidal.com'] failedAuth = false constructor(options: TidalOptions) { @@ -53,6 +59,7 @@ export default class Tidal implements Streamer { this.accessToken = options.accessToken this.refreshToken = options.refreshToken this.expires = options.expires + this.countryCode = options.countryCode const getReady = async () => { if (!this.refreshToken) return @@ -71,9 +78,10 @@ export default class Tidal implements Streamer { } } async #get(url: string, params: { [key: string]: string | number } = {}): Promise { - if (Date.now() > this.expires) await this.refresh() if (this.failedAuth) throw new Error(`Last request failed to authorize, get new tokens`) - params.countryCode = params.countryCode ?? 'US' + if (Date.now() > this.expires) await this.refresh() + if (!this.countryCode) await this.getCountryCode() + params.countryCode = params.countryCode ?? this.countryCode params.locale = params.locale ?? 'en_US' params.deviceType = params.deviceType ?? 'TV' for (const key in params) { @@ -112,6 +120,15 @@ export default class Tidal implements Streamer { }) return resp.ok } + async getCountryCode() { + const sessionResponse = await fetch('https://api.tidal.com/v1/sessions', { + headers: this.headers() + }) + if (sessionResponse.status != 200) return false + const sessionData = await sessionResponse.json() + this.countryCode = sessionData.countryCode + return true + } async getTokens() { const deviceAuthResponse = await fetch(`${TIDAL_AUTH_BASE}oauth2/device_authorization`, { method: 'post', @@ -151,6 +168,7 @@ export default class Tidal implements Streamer { this.accessToken = loginData.access_token this.refreshToken = loginData.refresh_token this.expires = Date.now() + loginData.expires_in * 1000 + await this.getCountryCode() console.log('[tidal] Using the following new config:', this.getCurrentConfig()) } @@ -164,7 +182,8 @@ export default class Tidal implements Streamer { tvSecret: this.tvSecret, accessToken: this.accessToken, refreshToken: this.refreshToken, - expires: this.expires + expires: this.expires, + countryCode: this.countryCode } } async refresh() {