Skip to content

Commit

Permalink
feat: audiobooks API
Browse files Browse the repository at this point in the history
  • Loading branch information
noook committed Jul 24, 2023
1 parent 8cab816 commit b375b89
Show file tree
Hide file tree
Showing 5 changed files with 365 additions and 1 deletion.
100 changes: 100 additions & 0 deletions src/api/audiobooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import type { GetAudiobookChapterOptions, GetAudiobookOptions, GetAudiobooksResponse, PaginatedResults, PaginationQueryOptions, SimplifiedAudiobookObject, SimplifiedChapterObject } from '../types'
import { ApiPart } from './api.part'

export class AudiobooksApi extends ApiPart {
/**
* Get Spotify catalog information for a single audiobook.
*
* **Note:** Audiobooks are only available for the US, UK, Ireland, New Zealand and Australia markets.
* @param id The [Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the audiobook.
*/
public getAudiobook(id: string, opts: GetAudiobookOptions = {}) {
return this.$fetch(`/audiobooks/${id}`, {
query: opts,
})
}

/**
* Get Spotify catalog information for several audiobooks identified by their Spotify IDs.
*
* **Note:** Audiobooks are only available for the US, UK, Ireland, New Zealand and Australia markets.
* @param ids A list of the Spotify IDs. For example: `ids=18yVqkdbdRvS24c0Ilj2ci,1HGw3J3NxZO1TP1BTtVhpZ`.
* @max `50` IDs.
*/
public getAudiobooks(ids: string[], opts: GetAudiobookOptions = {}): Promise<GetAudiobooksResponse[]> {
return this.$fetch<GetAudiobooksResponse[]>('/audiobooks', {
query: {
ids: ids.join(','),
...opts,
},
})
}

/**
* Get Spotify catalog information about an audiobook's chapters.
*
* **Note:** Audiobooks are only available for the US, UK, Ireland, New Zealand and Australia markets.
* @param opts
* @returns
*/
public getAudiobookChapters(id: string, opts: GetAudiobookChapterOptions = {}) {
return this.$fetch<PaginatedResults<SimplifiedChapterObject>>(`/audiobooks/${id}/chapters`, {
query: opts,
})
}

/**
* Get a list of the audiobooks saved in the current Spotify user's 'Your Music' library.
* @param opts
* @scope `user-library-read`
*/
public getSavedAudiobooks(opts: PaginationQueryOptions = {}): Promise<PaginatedResults<PaginatedResults<SimplifiedAudiobookObject>>> {
return this.$fetch<PaginatedResults<PaginatedResults<SimplifiedAudiobookObject>>>('/me/audiobooks', {
query: opts,
})
}

/**
* Save one or more audiobooks to the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @max `50` IDs.
* @scope `user-library-modify`
*/
public async saveAudiobooks(ids: string[]): Promise<void> {
await this.$fetch<void>('/me/audiobooks', {
method: 'PUT',
query: {
ids: ids.join(','),
},
})
}

/**
* Remove one or more audiobooks to the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @max `50` IDs.
* @scope `user-library-modify`
*/
public async removeAudiobooks(ids: string[]): Promise<void> {
await this.$fetch<void>('/me/audiobooks', {
method: 'DELETE',
query: {
ids: ids.join(','),
},
})
}

/**
* Check if one or more audiobooks are already saved in the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @max `50` IDs.
* @scope `user-library-read`
*/
public checkUserSavedAudiobooks(ids: string[]): Promise<boolean[]> {
return this.$fetch<boolean[]>('/me/audiobooks/contains', {
query: {
ids: ids.join(','),
},
})
}
}
5 changes: 4 additions & 1 deletion src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { $Fetch } from 'ofetch'
import { Headers, ofetch } from 'ofetch'
import { AlbumsApi, ArtistsApi, CategoriesApi, GenresApi, MarketsApi, PlayerApi, PlaylistsApi, SearchApi, UsersApi } from '.'
import { AlbumsApi, ArtistsApi, AudiobooksApi, CategoriesApi, GenresApi, MarketsApi, PlayerApi, PlaylistsApi, SearchApi, UsersApi } from '.'

export class SpotifyClient {
private token: null | string = null
Expand All @@ -20,6 +20,7 @@ export class SpotifyClient {

this.albums = new AlbumsApi(this.$fetch)
this.artists = new ArtistsApi(this.$fetch)
this.audiobooks = new AudiobooksApi(this.$fetch)
this.categories = new CategoriesApi(this.$fetch)
this.genres = new GenresApi(this.$fetch)
this.markets = new MarketsApi(this.$fetch)
Expand All @@ -39,6 +40,8 @@ export class SpotifyClient {

public artists: ArtistsApi

public audiobooks: AudiobooksApi

public categories: CategoriesApi

public genres: GenresApi
Expand Down
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './albums'
export * from './artists'
export * from './audiobooks'
export * from './categories'
export * from './genres'
export * from './markets'
Expand Down
259 changes: 259 additions & 0 deletions src/types/audiobook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
import type { CopyrightsObject, ExternalUrlObject, ImageObject, Market, PaginatedResults, PaginationQueryOptions } from './common'

export interface GetAudiobookOptions {
/**
* An [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. If a country code is specified,
* only content that is available in that market will be returned.
*/
market?: Market
}

export interface GetAudiobookChapterOptions extends PaginationQueryOptions, GetAudiobookOptions {}

export interface GetAudiobooksResponse {
audiobooks: AudiobookObject[]
}

export interface AudiobookAuthor {
/**
* The name of the author.
*/
name: string
}

export interface AudiobookNarrator {
/**
* The name of the narrator.
*/
name: string
}

export interface SimplifiedChapterObject {
/**
* A URL to a 30 second preview (MP3 format) of the episode. null if not available.
*/
audio_preview_url: string | null

/**
* /**
* A list of the countries in which the track can be played, identified by their
* [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code.
*/
available_markets: string[]

/**
* The number of the chapter
*/
chapter_number: number

/**
* A description of the audiobook. HTML tags are stripped away from this field, use `html_description` field in case HTML tags are needed.
*/
description: string

/**
* A description of the audiobook. This field may contain HTML tags.
*/
html_description: string

/**
* The episode length in milliseconds.
*/
duration_ms: number

/**
* Whether or not the audiobook has explicit content (`true` = yes it does; `false` = no it does not OR unknown).
*/
explicit: boolean

/**
* External URLs for this episode.
*/
external_urls: ExternalUrlObject

/**
* A link to the Web API endpoint providing full details of the episode.
*/
href: string

/**
* The [Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the episode.
*/
id: string

/**
* he cover art for the episode in various sizes, widest first.
*/
images: ImageObject[]

/**
* `true` if the episode is playable in the given market. Otherwise `false`.
*/
is_playable: boolean

/**
* A list of the languages used in the audiobook, identified by their [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code.
*/
languages: string[]

/**
* The name of the episode
*/
name: string

/**
* The date the episode was first released, for example `"1981-12-15"`. Depending on the precision, it might be shown as `"1981"` or `"1981-12"`.
*/
release_date: string

/**
* The precision with which `release_date` value is known.
*/
release_date_precision: 'year' | 'month' | 'day'

/**
* The user's most recent position in the episode. Set if the supplied access token is a user token and has the scope 'user-read-playback-position'.
*/
resume_point?: {
/**
* Whether or not the episode has been fully played by the user.
*/
fully_played: boolean

/**
* The user's most recent position in the episode in milliseconds.
*/
resume_position_ms: number
}

/**
* The object type.
*/
type: 'episode'

/**
* The [Spotify URI](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the episode.
*/
uri: string

/**
* Included in the response when a content restriction is applied.
*/
restrictions?: {
/**
* The reason for the restriction. Supported values:
* - `market` - The content item is not available in the given market.
* - `product` - The content item is not available for the user's subscription type.
* - `explicit` - The content item is explicit and the user's account is set to not play explicit content.
* - `payment_required` - Payment is required to play the content item.
*
* Additional reasons may be added in the future.
*
* **Note:** If you use this field, make sure that your application safely handles unknown values.
*/
reason: string
}
}

export interface AudiobookObject {
authors: AudiobookAuthor[]

/**
* /**
* A list of the countries in which the track can be played, identified by their
* [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code.
*/
available_markets: string[]

/**
* The copyright statements of the audiobook.
*/
copyrights: CopyrightsObject[]

/**
* A description of the audiobook. HTML tags are stripped away from this field, use `html_description` field in case HTML tags are needed.
*/
description: string

/**
* A description of the audiobook. This field may contain HTML tags.
*/
html_description: string

/**
* The edition of the audiobook.
*/
edition?: string

/**
* Whether or not the audiobook has explicit content (`true` = yes it does; `false` = no it does not OR unknown).
*/
explicit: boolean

/**
* External URLs for this audiobook.
*/
external_urls: ExternalUrlObject

/**
* A link to the Web API endpoint providing full details of the audiobook.
*/
href: string

/**
* The [Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the audiobook.
*/
id: string

/**
* he cover art for the audiobook in various sizes, widest first.
*/
images: ImageObject[]

/**
* A list of the languages used in the audiobook, identified by their [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code.
*/
languages: string[]

/**
* The media type of the audiobook.
*/
media_type: string

/**
* The name of the audiobook.
*/
name: string

/**
* The narrator(s) for the audiobook.
*/
narrators: AudiobookNarrator[]

/**
* The publisher of the audiobook.
*/
publisher: string

/**
* Allowed values: "audiobook"
*/
type: 'audiobook'

/**
* The [Spotify URI](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the audiobook.
*/
uri: string

/**
* The number of chapters in this audiobook.
*/
total_chapters: number

/**
* The chapters of the audiobook.
*/
chapters: PaginatedResults<SimplifiedChapterObject>
}

export type SimplifiedAudiobookObject = Omit<AudiobookObject, 'chapters'>
Loading

0 comments on commit b375b89

Please sign in to comment.