client.ts•6.31 kB
import {
AuthenticationType,
HttpMessageBody,
HttpMethod,
QueryParams,
httpClient,
} from '@activepieces/pieces-common';
import { SearchRequest, SearchResult } from './models/search';
import {
DeviceListResponse,
PlaybackPauseRequest,
PlaybackPlayRequest,
PlaybackSeekRequest,
PlaybackState,
PlaybackVolumeRequest,
} from './models/playback';
import {
Playlist,
PlaylistAddItemsRequest,
PlaylistCreateRequest,
PlaylistItem,
PlaylistRemoveItemsRequest,
PlaylistReorderItemsRequest,
PlaylistUpdateRequest,
} from './models/playlist';
import { User } from './models/user';
import { Pagination, PaginationRequest } from './models/common';
function emptyValueFilter(
accessor: (key: string) => any
): (key: string) => boolean {
return (key: string) => {
const val = accessor(key);
return (
val !== null &&
val !== undefined &&
(typeof val != 'string' || val.length > 0)
);
};
}
export function prepareQuery(request?: Record<string, any>): QueryParams {
const params: QueryParams = {};
if (!request) return params;
Object.keys(request)
.filter(emptyValueFilter((k) => request[k]))
.forEach((k: string) => {
params[k] = (request as Record<string, any>)[k].toString();
});
return params;
}
export class SpotifyWebApi {
constructor(private accessToken: string) {}
async makeRequest<T extends HttpMessageBody>(
method: HttpMethod,
url: string,
query?: QueryParams,
body?: object
): Promise<T> {
const res = await httpClient.sendRequest<T>({
method,
url: 'https://api.spotify.com/v1' + url,
queryParams: query,
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.accessToken,
},
});
return res.body;
}
async search(request: SearchRequest): Promise<SearchResult> {
const res = await this.makeRequest<SearchResult>(
HttpMethod.GET,
'/search',
prepareQuery(request)
);
return res;
}
async getDevices(): Promise<DeviceListResponse> {
return await this.makeRequest<DeviceListResponse>(
HttpMethod.GET,
'/me/player/devices'
);
}
async getPlaybackState(): Promise<PlaybackState> {
return await this.makeRequest<PlaybackState>(HttpMethod.GET, '/me/player');
}
async setVolume(request: PlaybackVolumeRequest) {
await this.makeRequest(
HttpMethod.PUT,
'/me/player/volume',
prepareQuery(request)
);
}
async pause(request: PlaybackPauseRequest) {
await this.makeRequest(
HttpMethod.PUT,
'/me/player/pause',
prepareQuery(request)
);
}
async play(request: PlaybackPlayRequest) {
const query: QueryParams = {};
if (request.device_id) query.device_id = request.device_id;
request.device_id = undefined;
await this.makeRequest(HttpMethod.PUT, '/me/player/play', query, request);
}
async seek(request: PlaybackSeekRequest) {
await this.makeRequest(
HttpMethod.PUT,
'/me/player/seek',
prepareQuery(request)
);
}
async getCurrentUser(): Promise<User> {
return await this.makeRequest<User>(HttpMethod.GET, '/me');
}
async getCurrentUserPlaylists(
request?: PaginationRequest
): Promise<Pagination<Playlist>> {
return await this.makeRequest<Pagination<Playlist>>(
HttpMethod.GET,
'/me/playlists',
prepareQuery(request)
);
}
async getAllCurrentUserPlaylists(): Promise<Playlist[]> {
const playlists: Playlist[] = [];
let total = 99999;
while (playlists.length < total) {
const res = await this.getCurrentUserPlaylists({
limit: 50,
offset: playlists.length,
});
total = res.total;
res.items.forEach((item) => playlists.push(item));
}
return playlists;
}
async createPlaylist(
userId: string,
request: PlaylistCreateRequest
): Promise<Playlist> {
return await this.makeRequest<Playlist>(
HttpMethod.POST,
'/users/' + userId + '/playlists',
undefined,
request
);
}
async updatePlaylist(id: string, request: PlaylistUpdateRequest) {
await this.makeRequest(
HttpMethod.PUT,
'/playlists/' + id,
undefined,
request
);
}
async getPlaylist(id: string): Promise<Playlist> {
return await this.makeRequest<Playlist>(HttpMethod.GET, '/playlists/' + id);
}
async getPlaylistItems(
id: string,
request?: PaginationRequest
): Promise<Pagination<PlaylistItem>> {
return await this.makeRequest<Pagination<PlaylistItem>>(
HttpMethod.GET,
'/playlists/' + id + '/tracks',
prepareQuery(request)
);
}
async getAllPlaylistItems(id: string): Promise<PlaylistItem[]> {
const items: PlaylistItem[] = [];
let total = 99999;
while (items.length < total) {
const res = await this.getPlaylistItems(id, {
limit: 50,
offset: items.length,
});
total = res.total;
res.items.forEach((item) => items.push(item));
}
return items;
}
async getSavedTracks(
request?: PaginationRequest
): Promise<Pagination<PlaylistItem>> {
return await this.makeRequest<Pagination<PlaylistItem>>(
HttpMethod.GET,
'/me/tracks',
prepareQuery(request)
);
}
async getAllSavedTracks(): Promise<PlaylistItem[]> {
const items: PlaylistItem[] = [];
let total = 99999;
while (items.length < total) {
const res = await this.getSavedTracks({
limit: 50,
offset: items.length,
});
total = res.total;
res.items.forEach((item) => items.push(item));
}
return items;
}
async addItemsToPlaylist(id: string, request: PlaylistAddItemsRequest) {
await this.makeRequest(
HttpMethod.POST,
'/playlists/' + id + '/tracks',
undefined,
request
);
}
async removeItemsFromPlaylist(
id: string,
request: PlaylistRemoveItemsRequest
) {
await this.makeRequest(
HttpMethod.DELETE,
'/playlists/' + id + '/tracks',
undefined,
request
);
}
async reorderPlaylist(id: string, request: PlaylistReorderItemsRequest) {
await this.makeRequest(
HttpMethod.PUT,
'/playlists/' + id + '/tracks',
undefined,
request
);
}
}